package com.zf.yichat.service.impl;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONArray;import com.alibaba.fastjson.JSONObject;import com.github.pagehelper.PageHelper;import com.zf.yichat.dto.*;import com.zf.yichat.mapper.*;import com.zf.yichat.model.*;import com.zf.yichat.service.*;import com.zf.yichat.service.config.ConfigSet;import com.zf.yichat.service.config.RedisService;import com.zf.yichat.service.dto.PacketSaleDetailDto;import com.zf.yichat.utils.YiChatMsgCode;import com.zf.yichat.utils.common.*;import com.zf.yichat.utils.response.FsPage;import com.zf.yichat.utils.response.FsResponse;import com.zf.yichat.utils.response.FsResponseGen;import com.zf.yichat.vo.*;import org.apache.commons.lang3.StringUtils;import org.hibernate.validator.internal.util.Contracts;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.scheduling.annotation.Async;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Isolation;import org.springframework.transaction.annotation.Transactional;import tk.mybatis.mapper.entity.Example;import java.math.BigDecimal;import java.util.*;import java.util.concurrent.TimeUnit;import java.util.stream.Collectors;/** * 一句话描述功能 * * @author fengsong * @date create in 15:17 2019/6/11 2019 */@Servicepublic class PacketServiceImpl implements PacketService {    @Autowired    private PacketMapper packetMapper;    @Autowired    private FanliService fanliService;    @Autowired    private FanliGoodsReceiveMapper fanliGoodsReceiveMapper;    @Autowired    private FanliGoodsGiveMapper fanliGoodsGiveMapper;    @Autowired    private PacketVideoMapper packetVideoMapper;    @Autowired    private PacketVideoRuleMapper packetVideoRuleMapper;    @Autowired    private PacketVipRuleMapper packetVipRuleMapper;    @Autowired    private PacketVipReceiveMapper packetVipReceiveMapper;    @Autowired    private PacketReceiveMapper packetReceiveMapper;    @Autowired    private PushService pushService;    @Autowired    private PacketSaleReceiveMapper packetSaleReceiveMapper;    @Autowired    private PacketSaleMapper packetSaleMapper;    @Autowired    private PacketMixuanMapper packetMixuanMapper;    @Autowired    private BalanceService balanceService;    @Autowired    private RedisService redisService;    @Autowired    private UserService userService;    @Autowired    private PacketCreateService packetCreateService;    @Autowired    private ConfigSet configSet;    @Autowired    private GroupService groupService;    @Autowired    private UserIntegralService userIntegralService;    @Autowired    private ImApiServiceImpl imApiService;    @Autowired    private SysDictService sysDictService;    @Autowired    private PacketSaleViewMapper packetSaleViewMapper;    @Autowired    private UserJoinChatroomMapper userJoinChatroomMapper;    @Autowired    private UserJoinUltragroupApplyMapper userJoinUltragroupApplyMapper;    @Value("${st.im_uri}")    private String imUri;    @Override    @Transactional(rollbackFor = Exception.class)    public Packet create(boolean isSingle, Integer srcType, Long userId, String password, Long receiveUserId, Integer num, BigDecimal money, String content, Long groupId, List<BigDecimal> packetList) {        Contracts.assertTrue(NumberUtils.scale2HalfUp(money).compareTo(money) == 0, YiChatMsgCode.SYSTEM_PARAM_ERROR.msg());        //判断是否实名认证        //   Contracts.assertTrue(userService.validStatus(userId), "未实名认证");        balanceService.checkPassword(userId, password);        Packet packet = new Packet();        packet.setMoney(money);        packet.setContent(content);        packet.setUserId(userId);        packet.setStatus(PacketStatus.NONE.getVal());        packet.setUserCount(0);        packet.setCtime(new Date());        packet.setNum(num);        packet.setOverStatus(0);        //检查余额是否充足 如果是是从余额发起的话        UserBalance balance = balanceService.selectByUserId(userId);//        if (srcType == 0) {        Contracts.assertTrue(balance.getIncomeBalance().compareTo(money) >= 0, YiChatMsgCode.PACKET_CREATE_NO_ENOUGH_BALANCE.msg());        Contracts.assertTrue(money.compareTo(NumberUtils.scale2HalfUp(new BigDecimal(0.01).multiply(new BigDecimal(1)))) >= 0, YiChatMsgCode.PACKET_CREATE_MONEY_LIMIT.msg());//        }//        boolean isSingle = Objects.nonNull(receiveUserId);        if (isSingle) {            //单聊红包            packet.setReceiveUser(receiveUserId);            if (srcType == 0) {              //  Contracts.assertTrue(NumberUtils.scale2HalfUp(new BigDecimal(num).multiply(new BigDecimal(200))).compareTo(money) >= 0, YiChatMsgCode.PACKET_SINGLE_MAX_OUT2.msg());                packet.setType(PacketType.single.getVal());            } else {              //  Contracts.assertTrue(NumberUtils.scale2HalfUp(new BigDecimal(num).multiply(new BigDecimal(10000))).compareTo(money) >= 0, YiChatMsgCode.PACKET_SINGLE_MAX_OUT.msg());                packet.setType(PacketType.transfer.getVal());            }        } else {            if (srcType == 0) {                //判断金额最大金额是否超过200                Contracts.assertTrue(NumberUtils.scale2HalfUp( new BigDecimal(200).multiply(new BigDecimal(num))).compareTo(money) >= 0, YiChatMsgCode.PACKET_CREATE_MAX_LIMIT.msg());                packet.setType(PacketType.group.getVal());            } else {                Contracts.assertTrue(num == 1, "专属红包数量只能为1");                //判断金额最大金额是否超过10000//                Contracts.assertTrue(NumberUtils.scale2HalfUp(new BigDecimal(num).multiply(new BigDecimal(5000))).compareTo(money) >= 0, YiChatMsgCode.PACKET_SINGLE_MAX_OUT.msg());                packet.setReceiveUser(receiveUserId);                packet.setType(PacketType.exclusive.getVal());            }            //群红包            packet.setGroupId(groupId);        }        packetMapper.insertUseGeneratedKeys(packet);        Contracts.assertNotNull(packet.getId(), YiChatMsgCode.SYSTEM_ERROR.msg());        //默认24小时后红包失效        if (packetList != null && packetList.size() != 0) {            redisService.setPacketList(packet, packetList, configSet.getPacket().getEffectHour());        } else {            redisService.setPacketList(packet, packetCreateService.construct(money, num), configSet.getPacket().getEffectHour());        }        //从创建人的可用余额划出金额到冻结余额中去        BalanceType type = BalanceType.CREATE_PACKET;        balanceService.update(userId, type, money, packet.getId(), isSingle ? "发单聊红包" : "发群聊红包");        return packet;    }    @Override    public PacketInfoDto detailWillDetele(Long packetId, Long userId) throws Exception {        PacketInfoDto dto = new PacketInfoDto();        Packet packet = selectById(packetId);        User user = userService.selectById(packet.getUserId());        List<PacketReceiveDto> list = packetReceiveMapper.selectList(packetId);        String userIdEncode = N3d.encode(userId);        list.forEach(v -> {            try {                v.setUserId(N3d.encode(v.getUserIdL()));                v.setUserIdL(null);            } catch (Exception e) {                e.printStackTrace();            }        });        Long lastGetTime = 0L;        dto.setSeconds(0L);        if (packet.getType().compareTo(PacketType.group.getVal()) == 0 || packet.getType().compareTo(PacketType.exclusive.getVal()) == 0) {            //结束才计算手气最佳            if (packet.getStatus().compareTo(PacketStatus.OVER.getVal()) == 0) {                Optional<PacketReceiveDto> userOp = list.stream().max(Comparator.comparing(PacketReceiveDto::getMoney));                if (userOp.isPresent()) {                    userOp.get().setMaxStatus(1);                }                Optional<PacketReceiveDto> lastTime = list.stream().max(Comparator.comparing(PacketReceiveDto::getCtime));                if (lastTime.isPresent()) {                    lastGetTime = lastTime.get().getCtime();                    dto.setSeconds(lastGetTime - (packet.getCtime().getTime() / 1000));                }            }        }        dto.setContent(packet.getContent());        dto.setMoney(packet.getMoney());        dto.setNick(user.getNick());        dto.setUserId(N3d.encode(user.getId()));        dto.setAvatar(user.getAvatar());        dto.setList(list);        dto.setPacketId(packetId);        if (Objects.nonNull(packet.getReceiveUser())) {            dto.setOnlyReceiveId(N3d.encode(packet.getReceiveUser()));        }        Integer status = packet.getStatus();        //如果是单聊且是发送人 状态为receive的状态为准        if (packet.getType().compareTo(PacketType.single.getVal()) == 0 || packet.getType().compareTo(PacketType.transfer.getVal()) == 0 && packet.getUserId().compareTo(userId) == 0) {            //status=packet.getStatus().compareTo()        } else {            //有领取判断当前用户是否领取 如果不是当前用户则返回未领取            if (status.compareTo(PacketStatus.DOING.getVal()) == 0) {                status = Optional.ofNullable(selectReceive(userId, packetId)).map(PacketReceive::getStatus).orElse(PacketStatus.NONE.getVal());            }        }        dto.setStatus((packet.getStatus() == 3 && packet.getOverStatus() == 1) ? PacketStatus.OVER.getVal() : status);        dto.setNum(packet.getNum());        dto.setReceiveNum(list.size());        dto.setReceiveMoney(list.stream().filter(v -> v.getUserId().equals(userIdEncode)).findFirst().map(m -> m.getMoney()).orElse(null));        dto.setcTime(packet.getCtime().getTime() / 1000);        logger.error("时间----》" + JSON.toJSONString(dto) + "=====" + packet.getCtime().getTime());        System.out.println("时间============》" + JSON.toJSONString(dto) + "=====" + packet.getCtime().getTime());        return dto;    }    @Override    @Transactional(rollbackFor = Exception.class)    public synchronized FsResponse receiveWillDetele(Long packetId, Long userId) throws Exception {        Packet packet = selectById(packetId);        if (packet.getOverStatus() == 1) {            return FsResponseGen.successData(YiChatMsgCode.PACKET_RECEIVE_NONE, selectListTest2222(packetId, userId));        }        boolean isOverTime = !(packet.getCtime().getTime() + configSet.getPacket().getEffectHour() * 60 * 60 * 1000L > System.currentTimeMillis());        if (isOverTime) {            return FsResponseGen.successData(YiChatMsgCode.PACKET_RECEIVE_OVER_TIME, selectListTest2222(packetId, userId));        }        //自己发送的单聊红包不能抢        if ((packet.getType().compareTo(PacketType.single.getVal()) == 0 || packet.getType().compareTo(PacketType.transfer.getVal()) == 0) && packet.getUserId().compareTo(userId) == 0) {            return FsResponseGen.successData(YiChatMsgCode.PACKET_RECEIVE_NONEMINE, selectListTest2222(packetId, userId));        }        String ultragroupIds= Optional.ofNullable(sysDictService.selectOne(DictKey.sys_ultra_groupids)).map(SysDict::getMemo).orElse("");        boolean isChatRoom=false;        if(packet.getGroupId()!=null){            if(ultragroupIds!=null){                String[] idsArray=ultragroupIds.split("#");                if(idsArray!=null){                    for(String groupIdTemp:idsArray){                        if(packet.getGroupId()==Long.valueOf(groupIdTemp)){                            isChatRoom=true;                            break;                        }                    }                }            }        }//        如果是群红包，判断是不是群成员        if (packet.getType().compareTo(PacketType.group.getVal()) == 0 || packet.getType().compareTo(PacketType.exclusive.getVal()) == 0 && packet.getGroupId() != null) {            if(isChatRoom){                if(!queryUserJoinUltragroupApp(String.valueOf(packet.getGroupId()) ,String.valueOf(userId)))                {                    //不在群聊天室成员列表中                    return FsResponseGen.fail(YiChatMsgCode.GROUP_MEMBER_NONE2);                }            }else {                //判断是否在群里                RcGroupMembers groupMembers = groupService.selectGroupMember(packet.getGroupId().intValue(), userId);                if (groupMembers == null || groupMembers.getIsdeleted()) {                    return FsResponseGen.fail(YiChatMsgCode.GROUP_MEMBER_NONE);                }                //非专属红包判断是否只有群管理可以领//                if (packet.getType().compareTo(PacketType.exclusive.getVal()) != 0) {//                    RcGroups groups = groupService.selectById(packet.getGroupId().intValue());//                    if (groups.getIsreceive() == 1) {//                        if (!GroupRole.MANAGER.getCode().equals(groupMembers.getRole()) && !GroupRole.CREATOR.getCode().equals(groupMembers.getRole())) {//                            return FsResponseGen.fail(YiChatMsgCode.GROUP_RECEIVE);//                        }//                    }//                }            }        }        BigDecimal val;        //专属红包判断是否专属领取人        if (Objects.nonNull(packet.getReceiveUser()) && !packet.getReceiveUser().equals(userId)) {            return FsResponseGen.failMsg("专属红包领取人错误");        }        if ("packet".equals(redisService.getVal("packet_" + packet.getId() + "_user_"))) {            try {                val = redisService.getReceive(packetId, userId);            } catch (Exception e) {                logger.error("lock error:{},{}", packet.getId(), e.getMessage());                throw e;            } finally {            }        } else {            val = redisService.getReceive(packetId, userId);        }        //已抢完        if (Objects.isNull(val)) {            return FsResponseGen.successData(YiChatMsgCode.PACKET_RECEIVE_NONE, selectListTest2222(packetId, userId));        }        //已抢过        if (val.compareTo(BigDecimal.ZERO) == 0) {            return FsResponseGen.successData(YiChatMsgCode.PACKET_RECEIVE_REPEAT, selectListTest2222(packetId, userId));        }        //领取逻辑        //1.插入记录        PacketReceive receive = new PacketReceive();        receive.setMoney(val);        receive.setPacketId(packet.getId());        //已领取        receive.setStatus(1);        receive.setUserId(userId);        packetReceiveMapper.insertSelective(receive);        //红包状态更新为已领取        packet.setStatus(PacketStatus.DOING.getVal());        //发送领取通知        PacketTipRequest packetTipRequest = new PacketTipRequest();        User user = userService.selectById(packet.getUserId());        //    User currentUser = userService.selectById(userId);//            new Thread(new Runnable() {//                @Override//                public void run() {//                    try {//                    packetTipRequest.setReceiveUserId(N3d.encode(userId));//                    packetTipRequest.setIsBest(0);//                    packetTipRequest.setRedPackgeId(Integer.parseInt(String.valueOf(packetId)));//                    packetTipRequest.setReceiveUserName(currentUser.getNick());//                    packetTipRequest.setObjectName("ST:RPTipMsg");//                    packetTipRequest.setSendUserId(N3d.encode(packet.getUserId()));//                    packetTipRequest.setSendUserName(user.getNick());//                    packetTipRequest.setTargetId(N3d.encode(packet.getGroupId()));//                    if(packet.getGroupId()!=null){//                        OKHttpUtil.httpPostJson("http://172.27.64.36:8081/misc/send/group/rptip", JSONObject.toJSONString(packetTipRequest));////                    }else {//                        OKHttpUtil.httpPostJson("http://172.27.64.36:8081/misc/send/single/rptip", JSONObject.toJSONString(packetTipRequest));////                    }////                    } catch (Exception e) {//                        e.printStackTrace();//                    }//                }//            }).start();        long leftNums = redisService.getPacketSize(packetId);        if (leftNums == 0) {            //红包领完            packet.setStatus(PacketStatus.OVER.getVal());            packet.setOverStatus(1);            if (packet.getGroupId() != null) {                //如果是群红包                //判断手气最佳                String luckMoney = redisService.getVal("packet_luck" + packet.getId());                if (String.valueOf(val).equals(luckMoney)) {                    //领取到手气最佳了,给自己的最佳总数+1                    if (redisService.getVal("user_luck" + userId) != null) {                        int luckCount = Integer.parseInt(redisService.getVal("user_luck" + userId));                        luckCount++;                        redisService.setVal("user_luck" + userId, String.valueOf(luckCount));                    } else {                        redisService.setVal("user_luck" + userId, "1");                    }                }                if(!isChatRoom){                    PacketSendRequest request = new PacketSendRequest();                    request.setContent(user.getNick());                    request.setEnvMsg("gdjsalgjow390jt3ngflsjg93j4tg3wmn4gw0m342gmsmvdlsmg03");                    try {                        request.setFrom(N3d.encode(packet.getUserId()));                        request.setTo(N3d.encode(packet.getGroupId()));                        request.setUserId(N3d.encode(packet.getUserId()));                        OKHttpUtil.httpPostJson(imUri + "misc/send/redtip", JSONObject.toJSONString(request));                    } catch (Exception e) {                        e.printStackTrace();                    }                }            }        }        packetMapper.updateByPrimaryKeySelective(packet);        //balanceService.update(packet.getUserId(),BalanceType.RECEIVE_PACKET_CREATOR,);        //领取者增加余额可支配金额        String m = null;        switch (packet.getType()) {            case 0:                m = "领取单聊红包";                break;            case 1:                m = "领取群聊红包";                break;            case 2:                m = "领取转账";                break;            case 3:                m = "领取群专属红包";                break;        }        balanceService.update(userId, BalanceType.RECEIVE_PACKET, val, packetId, m);        return FsResponseGen.successData(selectListTest2222(packetId, userId));    }    public boolean queryUserJoinUltragroupApp(String chatroomId,String userId) {        Integer count = userJoinUltragroupApplyMapper.queryUserJoinUltragroup(chatroomId, userId);        return count > 0;    }    @Override    public PacketInfoDto selectListTest2222(Long packetId, Long userId) throws Exception {        PacketInfoDto dto = new PacketInfoDto();        Packet packet = selectById(packetId);        User user = userService.selectById(packet.getUserId());        List<PacketReceiveDto> list = packetReceiveMapper.selectList(packetId);        String userIdEncode = N3d.encode(userId);        list.forEach(v -> {            try {                v.setUserId(N3d.encode(v.getUserIdL()));                v.setUserIdL(null);            } catch (Exception e) {                e.printStackTrace();            }        });        if (packet.getType().compareTo(PacketType.group.getVal()) == 0 || packet.getType().compareTo(PacketType.exclusive.getVal()) == 0) {            BigDecimal totalReceive = BigDecimal.ZERO;            for (PacketReceiveDto receive : list) {                totalReceive = totalReceive.add(receive.getMoney());            }            //判断红包是否已抢完            if (packet.getMoney().compareTo(totalReceive) == 0) {                packet.setStatus(PacketStatus.OVER.getVal());                packetMapper.updateByPrimaryKeySelective(packet);            }            //结束才计算手气最佳            if (packet.getStatus().compareTo(PacketStatus.OVER.getVal()) == 0) {                Optional<PacketReceiveDto> userOp = list.stream().max(Comparator.comparing(PacketReceiveDto::getMoney));                if (userOp.isPresent()) {                    userOp.get().setMaxStatus(1);                }            }        }        dto.setContent(packet.getContent());        dto.setMoney(packet.getMoney());        dto.setNick(user.getNick());        dto.setUserId(N3d.encode(user.getId()));        dto.setAvatar(user.getAvatar());        dto.setList(list);        dto.setPacketId(packetId);        if (Objects.nonNull(packet.getReceiveUser())) {            dto.setOnlyReceiveId(N3d.encode(packet.getReceiveUser()));        }        Integer status = packet.getStatus();        if (packet.getType().compareTo(PacketType.single.getVal()) == 0 || packet.getType().compareTo(PacketType.transfer.getVal()) == 0 && packet.getUserId().compareTo(userId) == 0) {            //status=packet.getStatus().compareTo()        } else {            if (status.compareTo(PacketStatus.DOING.getVal()) == 0) {                status = Optional.ofNullable(selectReceive(userId, packetId)).map(PacketReceive::getStatus).orElse(PacketStatus.NONE.getVal());            }        }        dto.setStatus((packet.getStatus() == 3 && packet.getOverStatus() == 1) ? PacketStatus.OVER.getVal() : status);        dto.setNum(packet.getNum());        dto.setReceiveNum(list.size());        dto.setReceiveMoney(list.stream().filter(v -> v.getUserId().equals(userIdEncode)).findFirst().map(m -> m.getMoney()).orElse(null));        return dto;    }    @Override    @Transactional(rollbackFor = Exception.class)    public FsResponse createManghe(Long userId, String password, BigDecimal money, Long orderId) {        //判断是否实名认证        logger.debug("接受的用户id" + userId);        //  Contracts.assertTrue(userService.realValidStatus(userId), "未实名认证");        balanceService.checkPassword(userId, password);        //检查余额是否充足 如果是是从余额发起的话        UserBalance balance = balanceService.selectByUserId(userId);        Contracts.assertTrue(money.compareTo(BigDecimal.ZERO) > 0, YiChatMsgCode.PACKET_CREATE_NO_ENOUGH_BALANCE.msg());        Contracts.assertTrue(balance.getIncomeBalance().compareTo(money) >= 0, YiChatMsgCode.PACKET_CREATE_NO_ENOUGH_BALANCE.msg());        //从创建人的可用余额划出金额到冻结余额中去        BalanceType type = BalanceType.CREATE_PACKET_MANGHE;        balanceService.update(userId, type, money, orderId, type.getDesc());        return FsResponseGen.success();    }    @Override    @Transactional(rollbackFor = Exception.class)    public FsResponse createMangheIntegral(Integer type, Long userId, String password, Integer integral, Long orderId) {        //判断是否实名认证        //   Contracts.assertTrue(userService.validStatus(userId), "未实名认证");        balanceService.checkPassword(userId, password);        //检查积分是否充足        User user = userService.selectById(userId);        Contracts.assertTrue(integral > 0, YiChatMsgCode.PACKET_CREATE_NO_ENOUGH_INTEGRAL.msg());        //增加积分        if (type == 0) {            userIntegralService.updateDetail(IntegralType.MANGHE_ADD, orderId.toString(), integral, userId);        } else {            Contracts.assertTrue(user.getIntegral() >= integral, YiChatMsgCode.PACKET_CREATE_NO_ENOUGH_INTEGRAL.msg());            userIntegralService.updateDetail(IntegralType.MANGHE_CONSUME, orderId.toString(), -integral, userId);        }        return FsResponseGen.success();    }    @Override    public Packet selectById(Long id) {        Packet packet = packetMapper.selectByPrimaryKey(id);        //超过24小时 状态变成        if (packet!=null&&packet.getCtime().getTime() + configSet.getPacket().getEffectHour() * 60 * 60 * 1000L < System.currentTimeMillis()) {            packet.setStatus(PacketStatus.OVER_TIME.getVal());        }        return packet;    }    @Override    @Transactional(rollbackFor = Exception.class)    public synchronized FsResponse receivePacket(Long packetId, Long userId) throws Exception {        Packet packet = selectById(packetId);        if(packet==null){            return  FsResponseGen.failMsg("红包不存在");        }        if (packet.getOverStatus() == 1) {            return FsResponseGen.successData(YiChatMsgCode.PACKET_RECEIVE_NONE, selectListTest(packetId, userId));        }        boolean isOverTime = !(packet.getCtime().getTime() + configSet.getPacket().getEffectHour() * 60 * 60 * 1000L > System.currentTimeMillis());        if (isOverTime) {            return FsResponseGen.successData(YiChatMsgCode.PACKET_RECEIVE_OVER_TIME, selectListTest(packetId, userId));        }        //自己发送的单聊红包不能抢        if ((packet.getType().compareTo(PacketType.single.getVal()) == 0 || packet.getType().compareTo(PacketType.transfer.getVal()) == 0) && packet.getUserId().compareTo(userId) == 0) {            return FsResponseGen.successData(YiChatMsgCode.PACKET_RECEIVE_NONEMINE, selectListTest(packetId, userId));        }        String ultragroupIds= Optional.ofNullable(sysDictService.selectOne(DictKey.sys_ultra_groupids)).map(SysDict::getMemo).orElse("");        boolean isChatRoom=false;        if(packet.getGroupId()!=null){            if(packet.getGroupId() >1000000000l){                isChatRoom=true;            }        } //       如果是群红包，判断是不是群成员        if (packet.getType().compareTo(PacketType.group.getVal()) == 0 || packet.getType().compareTo(PacketType.exclusive.getVal()) == 0 && packet.getGroupId() != null) {            if(isChatRoom){                if(!queryUserJoinUltragroupApp(String.valueOf(packet.getGroupId()) ,String.valueOf(userId)))                {                    //不在群聊天室成员列表中                    return FsResponseGen.fail(YiChatMsgCode.GROUP_MEMBER_NONE2);                }            }else {                //判断是否在群里                RcGroupMembers groupMembers = groupService.selectGroupMember(packet.getGroupId().intValue(), userId);                if (groupMembers == null || groupMembers.getIsdeleted()) {                    return FsResponseGen.fail(YiChatMsgCode.GROUP_MEMBER_NONE);                }                //非专属红包判断是否只有群管理可以领//                if (packet.getType().compareTo(PacketType.exclusive.getVal()) != 0) {//                    RcGroups groups = groupService.selectById(packet.getGroupId().intValue());//                    if (groups.getIsreceive() == 1) {//                        if (!GroupRole.MANAGER.getCode().equals(groupMembers.getRole()) && !GroupRole.CREATOR.getCode().equals(groupMembers.getRole())) {//                            return FsResponseGen.fail(YiChatMsgCode.GROUP_RECEIVE);//                        }//                    }//                }            }        }        BigDecimal val;        //专属红包判断是否专属领取人        if (Objects.nonNull(packet.getReceiveUser()) && !packet.getReceiveUser().equals(userId)) {            return FsResponseGen.failMsg("专属红包领取人错误");        }        if ("packet".equals(redisService.getVal("packet_" + packet.getId() + "_user_"))) {            try {                val = redisService.getReceive(packetId, userId);            } catch (Exception e) {                logger.error("lock error:{},{}", packet.getId(), e.getMessage());                throw e;            } finally {            }        } else {            val = redisService.getReceive(packetId, userId);        }        //已抢完        if (Objects.isNull(val)) {            return FsResponseGen.successData(YiChatMsgCode.PACKET_RECEIVE_NONE, selectListTest(packetId, userId));        }        //已抢过        if (val.compareTo(BigDecimal.ZERO) == 0) {            return FsResponseGen.successData(YiChatMsgCode.PACKET_RECEIVE_REPEAT, selectListTest(packetId, userId));        }        //领取逻辑        //1.插入记录        PacketReceive receive = new PacketReceive();        receive.setMoney(val);        receive.setPacketId(packet.getId());        //已领取        receive.setStatus(1);        receive.setUserId(userId);        packetReceiveMapper.insertSelective(receive);        //红包状态更新为已领取        packet.setStatus(PacketStatus.DOING.getVal());        //发送领取通知    //    PacketTipRequest packetTipRequest = new PacketTipRequest();        User user = userService.selectById(packet.getUserId());    //    User currentUser = userService.selectById(userId);//            new Thread(new Runnable() {//                @Override//                public void run() {//                    try {//                    packetTipRequest.setReceiveUserId(N3d.encode(userId));//                    packetTipRequest.setIsBest(0);//                    packetTipRequest.setRedPackgeId(Integer.parseInt(String.valueOf(packetId)));//                    packetTipRequest.setReceiveUserName(currentUser.getNick());//                    packetTipRequest.setObjectName("ST:RPTipMsg");//                    packetTipRequest.setSendUserId(N3d.encode(packet.getUserId()));//                    packetTipRequest.setSendUserName(user.getNick());//                    packetTipRequest.setTargetId(N3d.encode(packet.getGroupId()));//                    if(packet.getGroupId()!=null){//                        OKHttpUtil.httpPostJson("http://172.27.64.36:8081/misc/send/group/rptip", JSONObject.toJSONString(packetTipRequest));////                    }else {//                        OKHttpUtil.httpPostJson("http://172.27.64.36:8081/misc/send/single/rptip", JSONObject.toJSONString(packetTipRequest));////                    }////                    } catch (Exception e) {//                        e.printStackTrace();//                    }//                }//            }).start();        long leftNums = redisService.getPacketSize(packetId);        if (leftNums == 0) {            //红包领完            packet.setStatus(PacketStatus.OVER.getVal());            packet.setOverStatus(1);            if (packet.getGroupId() != null) {                //如果是群红包                //判断手气最佳                String luckMoney = redisService.getVal("packet_luck" + packet.getId());                if (String.valueOf(val).equals(luckMoney)) {                     //领取到手气最佳了,给自己的最佳总数+1                    if (redisService.getVal("user_luck" + userId) != null) {                        int luckCount = Integer.parseInt(redisService.getVal("user_luck" + userId));                        luckCount++;                         redisService.setVal("user_luck" + userId, String.valueOf(luckCount));                    } else {                         redisService.setVal("user_luck" + userId, "1");                    }                }                if(!isChatRoom){                    PacketSendRequest request = new PacketSendRequest();                    request.setContent(user.getNick());                    request.setEnvMsg("gdjsalgjow390jt3ngflsjg93j4tg3wmn4gw0m342gmsmvdlsmg03");                    try {                        request.setFrom(N3d.encode(packet.getUserId()));                        request.setTo(N3d.encode(packet.getGroupId()));                        request.setUserId(N3d.encode(packet.getUserId()));                        OKHttpUtil.httpPostJson(imUri + "misc/send/redtip", JSONObject.toJSONString(request));                    } catch (Exception e) {                        e.printStackTrace();                    }                }            }        }        packetMapper.updateByPrimaryKeySelective(packet);        //balanceService.update(packet.getUserId(),BalanceType.RECEIVE_PACKET_CREATOR,);        //领取者增加余额可支配金额        String m = null;        switch (packet.getType()) {            case 0:                m = "领取单聊红包";                break;            case 1:                m = "领取群聊红包";                break;            case 2:                m = "领取转账";                break;            case 3:                m = "领取群专属红包";                break;        }        balanceService.update(userId, BalanceType.RECEIVE_PACKET, val, packetId, m);        return FsResponseGen.successData(selectListTest(packetId, userId));    }    @Override    public synchronized FsResponse receivePacketOptimize(Long packetId, Long userId) throws Exception {        Packet packet = packetMapper.selectByPrimaryKey(packetId);        if (packet == null) {            return FsResponseGen.failMsg("红包不存在");        }        // 校验红包状态是否变成已超时        long effectHour = configSet.getPacket().getEffectHour();        long toMillis = TimeUnit.HOURS.toMillis(effectHour);        long overTime = packet.getCtime().getTime() + toMillis;        long currentTimeMillis = System.currentTimeMillis();        boolean isOverTime = currentTimeMillis > overTime;        JSONObject result = new JSONObject();        result.put("packetId", packetId);        // 校验是否过期        if (isOverTime) {            return FsResponseGen.successData(YiChatMsgCode.PACKET_RECEIVE_OVER_TIME, result);        }        // 校验是否已领取        if (PacketStatus.DOING.getVal() == packet.getOverStatus()) {            return FsResponseGen.successData(YiChatMsgCode.PACKET_RECEIVE_NONE, result);        }        // 判断是否可以抢红包        if (!userService.realValidStatus(userId)) {            throw new Exception("请先实名认证");        }        // 自己发送的单聊红包不能抢        if ((packet.getType().equals(PacketType.single.getVal()) || packet.getType().equals(PacketType.transfer.getVal())) && Objects.equals(packet.getUserId(), userId)) {            return FsResponseGen.successData(YiChatMsgCode.PACKET_RECEIVE_NONEMINE, result);        }        // 判断是否为群红包，并验证是否是群成员        Long groupId = packet.getGroupId();        boolean isChatRoom = groupId != null && groupId > 800200;        if (packet.getType().equals(PacketType.group.getVal()) || (packet.getType().equals(PacketType.exclusive.getVal()) && packet.getGroupId() != null)) {            if (isChatRoom) {                if (!queryUserJoinUltragroupApp(String.valueOf(packet.getGroupId()), String.valueOf(userId))) {                    return FsResponseGen.fail(YiChatMsgCode.GROUP_MEMBER_NONE);                }            } else {                Integer count = groupService.checkMemberInGroup(groupId.intValue(), userId);                if (count == 0) {                    return FsResponseGen.fail(YiChatMsgCode.GROUP_MEMBER_NONE);                }            }        }        // 判断专属红包领取人是否正确        if (Objects.nonNull(packet.getReceiveUser()) && !packet.getReceiveUser().equals(userId)) {            return FsResponseGen.failMsg("专属红包领取人错误");        }        // 获取红包金额        BigDecimal val =  redisService.getReceive(packetId, userId);        // 已抢完        if (Objects.isNull(val)) {            return FsResponseGen.successData(YiChatMsgCode.PACKET_RECEIVE_NONE, result);        }        // 已抢过        if (BigDecimal.ZERO.equals(val)) {            return FsResponseGen.successData(YiChatMsgCode.PACKET_RECEIVE_REPEAT, result);        }        // 领取逻辑        PacketReceive receive = new PacketReceive();        receive.setMoney(val);        receive.setPacketId(packet.getId());        receive.setStatus(1);        receive.setUserId(userId);        packetReceiveMapper.insertSelective(receive);        long leftNums = redisService.getPacketSize(packetId);        // 更新红包状态        if (leftNums == 0) {            handlePacketOver(val,packet, userId, isChatRoom);            // 更新红包状态和领取完状态            packet.setStatus(PacketStatus.OVER.getVal());            packet.setOverStatus(1);        } else {            packet.setStatus(PacketStatus.DOING.getVal());        }        // 单独更新状态        packetMapper.updateByPrimaryKeySelective(packet);        // 增加余额可支配金额        String msg;        switch (packet.getType()) {            case 0:                msg = "领取单聊红包";                break;            case 1:                msg = "领取群聊红包";                break;            case 2:                msg = "领取转账";                break;            case 3:                msg = "领取群专属红包";                break;            default:                msg = "";                break;        }        // 更新银行卡余额        balanceService.update(userId, BalanceType.RECEIVE_PACKET, val, packetId, msg);        return FsResponseGen.successData(result);    }    private void handlePacketOver(BigDecimal val, Packet packet, Long userId, boolean isChatRoom) {        Long packetId = packet.getId();        Long groupId = packet.getGroupId();        Long packetUserId = packet.getUserId();        // 如果是群红包        if (null != groupId) {            // 判断手气最佳            String luckMoney = redisService.getVal("packet_luck" + packetId);            if (String.valueOf(val).equals(luckMoney)) {                // 领取到手气最佳了，给自己的最佳总数+1                if (redisService.getVal("user_luck" + userId) != null) {                    int luckCount = Integer.parseInt(redisService.getVal("user_luck" + userId));                    luckCount++;                    redisService.setVal("user_luck" + userId, String.valueOf(luckCount));                } else {                    redisService.setVal("user_luck" + userId, "1");                }            }            // 发送领取通知            if (!isChatRoom) {                String nick = userService.selectNickNameById(packetUserId);                PacketSendRequest request = new PacketSendRequest();                request.setContent(nick);                request.setEnvMsg("gdjsalgjow390jt3ngflsjg93j4tg3wmn4gw0m342gmsmvdlsmg03");                try {                    request.setFrom(N3d.encode(packetUserId));                    request.setTo(N3d.encode(groupId));                    request.setUserId(N3d.encode(packetUserId));                    OKHttpUtil.httpPostJson(imUri + "misc/send/redtip", JSONObject.toJSONString(request));                } catch (Exception e) {                    e.printStackTrace();                }            }        }    }    @Override    @Transactional(rollbackFor = Exception.class)    public synchronized FsResponse receivePacketTest(Long packetId, Long userIdTest) throws Exception {        Packet packet = selectById(packetId);        if(packet==null){            return  FsResponseGen.failMsg("红包不存在");        }        if (packet.getOverStatus() == 1) {            return FsResponseGen.successData(YiChatMsgCode.PACKET_RECEIVE_NONE, selectListTest(packetId, userIdTest));        }        boolean isOverTime = !(packet.getCtime().getTime() + configSet.getPacket().getEffectHour() * 60 * 60 * 1000L > System.currentTimeMillis());        if (isOverTime) {            return FsResponseGen.successData(YiChatMsgCode.PACKET_RECEIVE_OVER_TIME, selectListTest(packetId, userIdTest));        }        //自己发送的单聊红包不能抢        if ((packet.getType().compareTo(PacketType.single.getVal()) == 0 || packet.getType().compareTo(PacketType.transfer.getVal()) == 0) && packet.getUserId().compareTo(userIdTest) == 0) {            return FsResponseGen.successData(YiChatMsgCode.PACKET_RECEIVE_NONEMINE, selectListTest(packetId, userIdTest));        }        String ultragroupIds= Optional.ofNullable(sysDictService.selectOne(DictKey.sys_ultra_groupids)).map(SysDict::getMemo).orElse("");        boolean isChatRoom=false;        if(packet.getGroupId()!=null){            if(ultragroupIds!=null){                String[] idsArray=ultragroupIds.split("#");                if(idsArray!=null){                    for(String groupIdTemp:idsArray){                        if(packet.getGroupId().equals(groupIdTemp)){                            isChatRoom=true;                            break;                        }                    }                }            }        }        //       如果是群红包，判断是不是群成员        if (packet.getType().compareTo(PacketType.group.getVal()) == 0 || packet.getType().compareTo(PacketType.exclusive.getVal()) == 0 && packet.getGroupId() != null) {            if(isChatRoom){            }else {                //判断是否在群里                RcGroupMembers groupMembers = groupService.selectGroupMember(packet.getGroupId().intValue(), userIdTest);//                if (groupMembers == null || groupMembers.getIsdeleted()) {//                    return FsResponseGen.fail(YiChatMsgCode.GROUP_MEMBER_NONE);//                }                //非专属红包判断是否只有群管理可以领//                if (packet.getType().compareTo(PacketType.exclusive.getVal()) != 0) {//                    RcGroups groups = groupService.selectById(packet.getGroupId().intValue());//                    if (groups.getIsreceive() == 1) {//                        if (!GroupRole.MANAGER.getCode().equals(groupMembers.getRole()) && !GroupRole.CREATOR.getCode().equals(groupMembers.getRole())) {//                            return FsResponseGen.fail(YiChatMsgCode.GROUP_RECEIVE);//                        }//                    }//                }            }        }        BigDecimal val;        //专属红包判断是否专属领取人        if (Objects.nonNull(packet.getReceiveUser()) && !packet.getReceiveUser().equals(userIdTest)) {            return FsResponseGen.failMsg("专属红包领取人错误");        }        if ("packet".equals(redisService.getVal("packet_" + packet.getId() + "_user_"))) {            try {                val = redisService.getReceive(packetId, userIdTest);            } catch (Exception e) {                logger.error("lock error:{},{}", packet.getId(), e.getMessage());                throw e;            } finally {            }        } else {            val = redisService.getReceive(packetId, userIdTest);        }        //已抢完        if (Objects.isNull(val)) {            return FsResponseGen.successData(YiChatMsgCode.PACKET_RECEIVE_NONE, selectListTest(packetId, userIdTest));        }        //已抢过        if (val.compareTo(BigDecimal.ZERO) == 0) {            return FsResponseGen.successData(YiChatMsgCode.PACKET_RECEIVE_REPEAT, selectListTest(packetId, userIdTest));        }        //领取逻辑        //1.插入记录        PacketReceive receive = new PacketReceive();        receive.setMoney(val);        receive.setPacketId(packet.getId());        //已领取        receive.setStatus(1);        receive.setUserId(userIdTest);        packetReceiveMapper.insertSelective(receive);        //红包状态更新为已领取        packet.setStatus(PacketStatus.DOING.getVal());        //发送领取通知        //    PacketTipRequest packetTipRequest = new PacketTipRequest();        User user = userService.selectById(packet.getUserId());        //    User currentUser = userService.selectById(userId);//            new Thread(new Runnable() {//                @Override//                public void run() {//                    try {//                    packetTipRequest.setReceiveUserId(N3d.encode(userId));//                    packetTipRequest.setIsBest(0);//                    packetTipRequest.setRedPackgeId(Integer.parseInt(String.valueOf(packetId)));//                    packetTipRequest.setReceiveUserName(currentUser.getNick());//                    packetTipRequest.setObjectName("ST:RPTipMsg");//                    packetTipRequest.setSendUserId(N3d.encode(packet.getUserId()));//                    packetTipRequest.setSendUserName(user.getNick());//                    packetTipRequest.setTargetId(N3d.encode(packet.getGroupId()));//                    if(packet.getGroupId()!=null){//                        OKHttpUtil.httpPostJson("http://172.27.64.36:8081/misc/send/group/rptip", JSONObject.toJSONString(packetTipRequest));////                    }else {//                        OKHttpUtil.httpPostJson("http://172.27.64.36:8081/misc/send/single/rptip", JSONObject.toJSONString(packetTipRequest));////                    }////                    } catch (Exception e) {//                        e.printStackTrace();//                    }//                }//            }).start();        long leftNums = redisService.getPacketSize(packetId);        if (leftNums == 0) {            //红包领完            packet.setStatus(PacketStatus.OVER.getVal());            packet.setOverStatus(1);            if (packet.getGroupId() != null) {                //如果是群红包                //判断手气最佳                String luckMoney = redisService.getVal("packet_luck" + packet.getId());                if (String.valueOf(val).equals(luckMoney)) {                    //领取到手气最佳了,给自己的最佳总数+1                    if (redisService.getVal("user_luck" + userIdTest) != null) {                        int luckCount = Integer.parseInt(redisService.getVal("user_luck" + userIdTest));                        luckCount++;                        redisService.setVal("user_luck" + userIdTest, String.valueOf(luckCount));                    } else {                        redisService.setVal("user_luck" + userIdTest, "1");                    }                }                if(!isChatRoom){                    PacketSendRequest request = new PacketSendRequest();                    request.setContent(user.getNick());                    request.setEnvMsg("gdjsalgjow390jt3ngflsjg93j4tg3wmn4gw0m342gmsmvdlsmg03");                    try {                        request.setFrom(N3d.encode(packet.getUserId()));                        request.setTo(N3d.encode(packet.getGroupId()));                        request.setUserId(N3d.encode(packet.getUserId()));                        OKHttpUtil.httpPostJson(imUri + "misc/send/redtip", JSONObject.toJSONString(request));                    } catch (Exception e) {                        e.printStackTrace();                    }                }            }        }        packetMapper.updateByPrimaryKeySelective(packet);        //balanceService.update(packet.getUserId(),BalanceType.RECEIVE_PACKET_CREATOR,);        //领取者增加余额可支配金额        String m = null;        switch (packet.getType()) {            case 0:                m = "领取单聊红包";                break;            case 1:                m = "领取群聊红包";                break;            case 2:                m = "领取转账";                break;            case 3:                m = "领取群专属红包";                break;        }        balanceService.update(userIdTest, BalanceType.RECEIVE_PACKET, val, packetId, m);        return FsResponseGen.successData(selectListTest(packetId, userIdTest));    }//    public boolean queryUserJoinChatroom(String chatroomId,String userId) {//        Integer count = userJoinChatroomMapper.queryUserJoinChatroom(chatroomId, userId);//        return count > 0;//    }    @Override    public PacketInfoDto selectListTest(Long packetId, Long userId) throws Exception {        PacketInfoDto dto = new PacketInfoDto();        dto.setPacketId(packetId);//        Packet packet = selectById(packetId);//        User user = userService.selectById(packet.getUserId());//        List<PacketReceiveDto> list = packetReceiveMapper.selectList(packetId);////        String userIdEncode = N3d.encode(userId);//        list.forEach(v -> {//            try {//                v.setUserId(N3d.encode(v.getUserIdL()));//                v.setUserIdL(null);//            } catch (Exception e) {//                e.printStackTrace();//            }//        });////        if (packet.getType().compareTo(PacketType.group.getVal()) == 0 || packet.getType().compareTo(PacketType.exclusive.getVal()) == 0) {////            BigDecimal totalReceive = BigDecimal.ZERO;////            for (PacketReceiveDto receive : list) {//                totalReceive = totalReceive.add(receive.getMoney());//            }//            //判断红包是否已抢完//            if (packet.getMoney().compareTo(totalReceive) == 0) {//                packet.setStatus(PacketStatus.OVER.getVal());//                packetMapper.updateByPrimaryKeySelective(packet);//            }////            //结束才计算手气最佳//            if (packet.getStatus().compareTo(PacketStatus.OVER.getVal()) == 0) {//                Optional<PacketReceiveDto> userOp = list.stream().max(Comparator.comparing(PacketReceiveDto::getMoney));//                if (userOp.isPresent()) {//                    userOp.get().setMaxStatus(1);//                }//            }//        }//////        dto.setContent(packet.getContent());//        dto.setMoney(packet.getMoney());//        dto.setNick(user.getNick());//        dto.setUserId(N3d.encode(user.getId()));//        dto.setAvatar(user.getAvatar());//        dto.setList(list);//        dto.setPacketId(packetId);//        if (Objects.nonNull(packet.getReceiveUser())) {//            dto.setOnlyReceiveId(N3d.encode(packet.getReceiveUser()));//        }//        Integer status = packet.getStatus();//        if (packet.getType().compareTo(PacketType.single.getVal()) == 0 || packet.getType().compareTo(PacketType.transfer.getVal()) == 0 && packet.getUserId().compareTo(userId) == 0) {//            //status=packet.getStatus().compareTo()//        } else {//            if (status.compareTo(PacketStatus.DOING.getVal()) == 0) {//                PacketReceive myReceived = selectReceive(userId, packetId);//                status = Optional.ofNullable(myReceived).map(PacketReceive::getStatus).orElse(PacketStatus.NONE.getVal());//                if(myReceived!=null ){//                    dto.setMyRceiveMoney(myReceived.getMoney());//                }else {//                    dto.setMyRceiveMoney(new BigDecimal("0.00"));//                }//            }//        }//        dto.setStatus((packet.getStatus() == 3 && packet.getOverStatus() == 1) ? PacketStatus.OVER.getVal() : status);//        dto.setNum(packet.getNum());//        dto.setReceiveNum(list.size());//        dto.setReceiveMoney(list.stream().filter(v -> v.getUserId().equals(userIdEncode)).findFirst().map(m -> m.getMoney()).orElse(null));        return dto;    }    private PacketReceive selectReceive(Long userId, Long packetId) {        Example sel = new Example(PacketReceive.class);        sel.createCriteria().andEqualTo("userId", userId).andEqualTo("packetId", packetId);        return packetReceiveMapper.selectOneByExample(sel);    }    @Override    public PacketInfoDto packetDtail(Long packetId, Long userId) throws Exception {        PacketInfoDto dto = new PacketInfoDto();        Packet packet = selectById(packetId);        User user = userService.selectById(packet.getUserId());//        List<PacketReceiveDto> list = packetReceiveMapper.selectList(packetId);//        String userIdEncode = N3d.encode(userId);//        list.forEach(v -> {//            try {//                v.setUserId(N3d.encode(v.getUserIdL()));//                v.setUserIdL(null);//            } catch (Exception e) {//                e.printStackTrace();//            }//        });//        Long lastGetTime = 0L;//        dto.setSeconds(0L);//        if (packet.getType().compareTo(PacketType.group.getVal()) == 0 || packet.getType().compareTo(PacketType.exclusive.getVal()) == 0) {////            //结束才计算手气最佳//            if (packet.getStatus().compareTo(PacketStatus.OVER.getVal()) == 0) {//                Optional<PacketReceiveDto> userOp = list.stream().max(Comparator.comparing(PacketReceiveDto::getMoney));//                if (userOp.isPresent()) {//                    userOp.get().setMaxStatus(1);//                }////                Optional<PacketReceiveDto> lastTime = list.stream().max(Comparator.comparing(PacketReceiveDto::getCtime));//                if (lastTime.isPresent()) {//                    lastGetTime = lastTime.get().getCtime();//                    dto.setSeconds(lastGetTime - (packet.getCtime().getTime() / 1000));//                }//            }//        }        dto.setContent(packet.getContent());        dto.setMoney(packet.getMoney());        dto.setNick(user.getNick());        dto.setUserId(N3d.encode(user.getId()));        dto.setAvatar(user.getAvatar());        dto.setList(new ArrayList<>());        dto.setPacketId(packetId);        if (Objects.nonNull(packet.getReceiveUser())) {            dto.setOnlyReceiveId(N3d.encode(packet.getReceiveUser()));        }        Integer status = packet.getStatus();        //如果是单聊且是发送人 状态为receive的状态为准        if (packet.getType().compareTo(PacketType.single.getVal()) == 0 || packet.getType().compareTo(PacketType.transfer.getVal()) == 0 && packet.getUserId().compareTo(userId) == 0) {            //status=packet.getStatus().compareTo()        } else {            //有领取判断当前用户是否领取 如果不是当前用户则返回未领取            PacketReceive myReceived = selectReceive(userId, packetId);            if(myReceived!=null ){                dto.setMyRceiveMoney(myReceived.getMoney());            }else {                dto.setMyRceiveMoney(new BigDecimal("0.00"));            }            if (status.compareTo(PacketStatus.DOING.getVal()) == 0) {                status = Optional.ofNullable(myReceived).map(PacketReceive::getStatus).orElse(PacketStatus.NONE.getVal());            }        }        dto.setStatus((packet.getStatus() == 3 && packet.getOverStatus() == 1) ? PacketStatus.OVER.getVal() : status);        dto.setNum(packet.getNum());        dto.setReceiveNum(packetMapper.countReceiveCount(packetId));        dto.setReceiveMoney( packetMapper.queryReceivedMoney(packetId));        dto.setcTime(packet.getCtime().getTime() / 1000);        //   logger.error("时间----》" + JSON.toJSONString(dto) + "=====" + packet.getCtime().getTime());        // System.out.println("时间============》" + JSON.toJSONString(dto) + "=====" + packet.getCtime().getTime());        return dto;    }    @Override    public PacketInfoDto packetDetailOptimize(Long packetId, Long userId) throws Exception {        PacketInfoDto dto = packetMapper.queryPacketInfoDetails(packetId, userId);        if (null == dto) {            return dto;        }        dto.setUserId(N3d.encode(dto.getPackUserId()));        dto.setList(new ArrayList<>());        String onlyReceiveId = dto.getOnlyReceiveId();        if (Objects.nonNull(dto.getOnlyReceiveId())) {            dto.setOnlyReceiveId(N3d.encode(Long.valueOf(onlyReceiveId)));        }        dto.setStatus((dto.getStatus() == 3 && dto.getOverStatus() == 1) ? PacketStatus.OVER.getVal() : dto.getIsReceived());        return dto;    }   //红包详情老方法，适用于领取人数很少的场景    public PacketInfoDto detailOld(Long packetId, Long userId) throws Exception {        PacketInfoDto dto = new PacketInfoDto();        Packet packet = selectById(packetId);        User user = userService.selectById(packet.getUserId());        List<PacketReceiveDto> list = packetReceiveMapper.selectList(packetId);        String userIdEncode = N3d.encode(userId);        list.forEach(v -> {            try {                v.setUserId(N3d.encode(v.getUserIdL()));                v.setUserIdL(null);            } catch (Exception e) {                e.printStackTrace();            }        });        Long lastGetTime = 0L;        dto.setSeconds(0L);        if (packet.getType().compareTo(PacketType.group.getVal()) == 0 || packet.getType().compareTo(PacketType.exclusive.getVal()) == 0) {            //结束才计算手气最佳            if (packet.getStatus().compareTo(PacketStatus.OVER.getVal()) == 0) {                Optional<PacketReceiveDto> userOp = list.stream().max(Comparator.comparing(PacketReceiveDto::getMoney));                if (userOp.isPresent()) {                    userOp.get().setMaxStatus(1);                }                Optional<PacketReceiveDto> lastTime = list.stream().max(Comparator.comparing(PacketReceiveDto::getCtime));                if (lastTime.isPresent()) {                    lastGetTime = lastTime.get().getCtime();                    dto.setSeconds(lastGetTime - (packet.getCtime().getTime() / 1000));                }            }        }        dto.setContent(packet.getContent());        dto.setMoney(packet.getMoney());        dto.setNick(user.getNick());        dto.setUserId(N3d.encode(user.getId()));        dto.setAvatar(user.getAvatar());        dto.setList(list);        dto.setPacketId(packetId);        if (Objects.nonNull(packet.getReceiveUser())) {            dto.setOnlyReceiveId(N3d.encode(packet.getReceiveUser()));        }        Integer status = packet.getStatus();        //如果是单聊且是发送人 状态为receive的状态为准        if (packet.getType().compareTo(PacketType.single.getVal()) == 0 || packet.getType().compareTo(PacketType.transfer.getVal()) == 0 && packet.getUserId().compareTo(userId) == 0) {            //status=packet.getStatus().compareTo()        } else {            //有领取判断当前用户是否领取 如果不是当前用户则返回未领取            if (status.compareTo(PacketStatus.DOING.getVal()) == 0) {                status = Optional.ofNullable(selectReceive(userId, packetId)).map(PacketReceive::getStatus).orElse(PacketStatus.NONE.getVal());            }        }        dto.setStatus((packet.getStatus() == 3 && packet.getOverStatus() == 1) ? PacketStatus.OVER.getVal() : status);        dto.setNum(packet.getNum());        dto.setReceiveNum(list.size());        dto.setReceiveMoney(list.stream().filter(v -> v.getUserId().equals(userIdEncode)).findFirst().map(m -> m.getMoney()).orElse(null));        dto.setcTime(packet.getCtime().getTime() / 1000);     //   logger.error("时间----》" + JSON.toJSONString(dto) + "=====" + packet.getCtime().getTime());       // System.out.println("时间============》" + JSON.toJSONString(dto) + "=====" + packet.getCtime().getTime());        return dto;    }    @Override    public PacketSendInfoDto countSendMoney(PacketType type, Long userId) {        PacketSendInfoDto dto = packetMapper.selectSendCount(type.getVal(), userId);        if (Objects.isNull(dto.getMoney())) {            dto.setMoney(new BigDecimal("0.00"));        }        return dto;    }    @Override    public PacketReceiveInfoDto countReceiveMoney(PacketType type, Long userId) {        PacketReceiveInfoDto dto = packetMapper.selectReceiveCount(type.getVal(), userId);        if (Objects.isNull(dto.getMoney())) {            dto.setMoney(new BigDecimal("0.00"));        }        if(redisService.getVal("user_luck" + userId)!=null){            int luckCount = Integer.parseInt(redisService.getVal("user_luck" + userId));            logger.error("luckMoney===>6==>"+String.valueOf(luckCount+"===="+userId));            dto.setLuckCount(Long.valueOf(luckCount));        }else {            dto.setLuckCount(0l);        }        return dto;    }    @Override    public PacketSendInfoDto countSaleSendMoney(Long userId) {        PacketSendInfoDto dto = packetSaleMapper.selectSaleSendCount(userId);        if (Objects.isNull(dto.getMoney())) {            dto.setMoney(new BigDecimal("0.00"));        }        return dto;    }    @Override    public PacketReceiveInfoDto countSaleReceiveMoney(Long userId) {        PacketReceiveInfoDto dto = packetSaleMapper.selectSaleReceiveCount(userId);        if (Objects.isNull(dto.getMoney())) {            dto.setMoney(new BigDecimal("0.00"));        }        return dto;    }    @Override    public FsResponse selectSendList(FsPage page, PacketType type, Long userId) {        PageHelper.startPage(page.getPageNo(), page.getPageSize());        return DtoChangeUtils.getPageList(packetMapper.selectSendList(type.getVal(), userId), v -> {            v.setReceiveCount(packetMapper.countReceiveCount(v.getPacketId()));            return v;        });    }    @Override    public FsResponse selectReceiveList(FsPage page, PacketType type, Long userId) {        PageHelper.startPage(page.getPageNo(), page.getPageSize());        return DtoChangeUtils.getPageList(packetMapper.selectReceiveList(type.getVal(), userId), v -> v);    }    @Override    public FsResponse selectSaleSendList(FsPage page, Long userId) {        PageHelper.startPage(page.getPageNo(), page.getPageSize());        return DtoChangeUtils.getPageList(packetSaleMapper.selectSaleSendList(userId), v -> v);    }    @Override    public FsResponse selectMixuanSendList(FsPage page, Long userId) {        PageHelper.startPage(page.getPageNo(), page.getPageSize());        return DtoChangeUtils.getPageList(packetMixuanMapper.selectSendList(userId), v -> getPacketMixuanDetailDto(v, null));    }    @Override    public FsResponse selectSaleReceiveList(FsPage page, Long userId) {        PageHelper.startPage(page.getPageNo(), page.getPageSize());        return DtoChangeUtils.getPageList(packetSaleMapper.selectSaleReceiveList(userId), v -> v);    }    @Override    public FsResponse selectSaleReceiveMemberList(FsPage page, Long packetId, Long userId) {        PacketSale copy = packetSaleMapper.selectByPrimaryKey(packetId);        if (Objects.isNull(copy) || copy.getStatus() == 1 || !Objects.equals(userId, copy.getUserId())) {            return FsResponseGen.fail(YiChatMsgCode.PACKET_NONE);        }        PageHelper.startPage(page.getPageNo(), page.getPageSize());        return DtoChangeUtils.getPageList(packetSaleMapper.selectSaleReceiveMemberList(packetId), v -> v);    }    private Logger logger = LoggerFactory.getLogger(getClass());    @Override    public void packetTimeoutBack() {        //查询所有超时的红包        Example example = new Example(Packet.class);        example.createCriteria().andLessThan("ctime", DateUtils.formatDate(new Date(System.currentTimeMillis() - configSet.getPacket().getEffectHour() * 60 * 60 * 1000L), "yyyy-MM-dd HH:mm:ss")).andNotEqualTo("status", PacketStatus.OVER_TIME.getVal());        List<Packet> timeList = packetMapper.selectByExample(example);        if (GeneralUtils.isNotNullOrEmpty(timeList)) {            packetBack(timeList);        }    }    @Transactional(rollbackFor = Exception.class, isolation = Isolation.SERIALIZABLE)    void packetBack(List<Packet> timeList) {        timeList.forEach(v -> {            //如果已抢完 则直接修改状态            if (v.getStatus().compareTo(PacketStatus.OVER.getVal()) != 0) {                //查询未领取红包退回                Example sel = new Example(PacketReceive.class);                sel.createCriteria().andEqualTo("status", 1).andEqualTo("packetId", v.getId());                List<PacketReceive> re = packetReceiveMapper.selectByExample(sel);                BigDecimal noneReceive = v.getMoney();                if (GeneralUtils.isNotNullOrEmpty(re)) {                    BigDecimal receive = re.stream().map(PacketReceive::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add);                    noneReceive = v.getMoney().subtract(receive);                }                //还未待领取的红包                if (noneReceive.compareTo(BigDecimal.ZERO) > 0) {//                        logger.debug("红包[{}]还有金额【{}】超时未被领取", v.getId(), noneReceive);                    if (noneReceive.compareTo(BigDecimal.ZERO) > 0) {                        balanceService.update(v.getUserId(), BalanceType.RETURN_PACKET, noneReceive, v.getId(), (v.getType() == 0 ? "单聊" : v.getType() == 1 ? "群聊" : "转账") + "红包超时退回");                        pushService.sendServiceSingle(1, null, null, v.getId(), v.getUserId(), "红包超时退回", noneReceive, "红包超时退回【" + noneReceive + "】", false);                    }                } else {//                        logger.debug("红包[{}]已被领完", v.getId());                }            }            v.setStatus(PacketStatus.OVER_TIME.getVal());            packetMapper.updateByPrimaryKeySelective(v);            //删除redis key            redisService.deleteKey(v.getId());//                logger.debug("红包[{}]状态变更为超时", v.getId());        });    }    /**     * 慎用,给系统用户增加营销红包余额     */    @Override    public void packetSaleAddForSystem() {        Long lastUser = Long.valueOf(15001615);//15001615是20个系统用户前的第一个正常用户        Random random = new Random();        for (int i = 0; i < 20; i++) {            Double d = random.nextDouble() * 200;            balanceService.update(lastUser + i + 1, BalanceType.PACKET_SALE_GET, NumberUtils.halfTwo(new BigDecimal(d)), (long) 0, "领取营销红包");        }    }    /**     * 发放视频红包（系统自动和后台手动发放）     */    @Override    public void packetVideoGiftBySystem() {        Example example = new Example(PacketVideoRule.class);        example.createCriteria().andEqualTo("status", 1);        PacketVideoRule rule = packetVideoRuleMapper.selectOneByExample(example);        if (Objects.nonNull(rule)) {            List<BigDecimal> moneyList = packetCreateService.constructVideoPacket(rule.getTotalMoney(), rule.getNum(), rule.getMinMoney(), rule.getMaxMoney());            List<Integer> timeList = packetCreateService.constructVideoTime(rule.getTotalTime(), rule.getNum(), rule.getMinTime(), rule.getMaxTime());            redisService.setPacketVideo(moneyList, timeList, rule.getForceValid() == 1 ? true : false);        }    }    //    /**    //     * 慎用,给系统用户初始化营销红包余额    //     */    //    @Override    //    public void packetSaleInitForSystem() {    //        Long lastUser = Long.valueOf(15001615);//15001615是20个系统用户前的第一个正常用户    //        Random random = new Random();    //        for (int i = 0; i < 20; i++) {    //            Double d = random.nextDouble() + 10000;    //            balanceService.update(lastUser + i + 1, BalanceType.PACKET_SALE_GET, NumberUtils.halfTwo(new BigDecimal(d)), (long) 0, "领取营销红包");    //        }    //    }    @Override    @Transactional(rollbackFor = Exception.class)    public FsResponse createSale(Long userId, BigDecimal money, Integer num, String name, String content, String imgs, String video, String thumbnail, Integer contactStatus, String linkUrl, Integer linkUrlStatus, String location, BigDecimal longitude, BigDecimal latitude, Integer limitDistance, String question, String answer, String tip, Integer type) {        //检查余额是否充足 如果是是从余额发起的话        UserBalance balance = balanceService.selectByUserId(userId);        //手续费        BigDecimal commission = new BigDecimal(Optional.ofNullable(sysDictService.selectOne(DictKey.packet_sale_commission)).map(SysDict::getValue).orElse("0"));        commission = NumberUtils.halfTwo(money.multiply(commission));        //判断余额是否足够        if (balance.getIncomeBalance().compareTo(money.add(commission)) < 0) {            return FsResponseGen.fail(YiChatMsgCode.PACKET_CREATE_NO_ENOUGH_BALANCE);        }        //减去手续费        //money = money.subtract(commission);        if (money.compareTo(NumberUtils.scale2HalfUp(new BigDecimal(0.01).multiply(new BigDecimal(1)))) < 0) {            return FsResponseGen.fail(YiChatMsgCode.PACKET_CREATE_MONEY_LIMIT);        }        if (new BigDecimal(100).compareTo(money.divide(new BigDecimal(num), 2, BigDecimal.ROUND_HALF_UP)) < 0) {            return FsResponseGen.failMsg("红包平均值不能大于100");        }        //主体数据保存        Date currentDate = new Date();        PacketSale packet = new PacketSale();        //待审核        packet.setCheckStatus(CheckStatus.WAIT.getVal());        packet.setStatus(0);        packet.setName(name);        packet.setContent(content);        packet.setCtime(currentDate);        packet.setStartTime(currentDate);        packet.setCommission(commission);        packet.setQuestion(question);        packet.setAnswer(answer);        packet.setTip(tip);        packet.setMoney(money);        packet.setNum(num);        packet.setUserId(userId);        packet.setUserCount(0);        packet.setOverStatus(0);        packet.setType(type == null ? 0 : type);        packet.setExternal(0);        packet.setImgs(imgs);        packet.setContactStatus(contactStatus);        packet.setLinkUrl(linkUrl);        packet.setVideo(video);        packet.setThumbnail(thumbnail);        packet.setLinkUrlStatus(linkUrlStatus);        packet.setLongitude(longitude);        packet.setLatitude(latitude);        packet.setLimitDistance(limitDistance);        packetSaleMapper.insertUseGeneratedKeys(packet);        balanceService.update(userId, BalanceType.PACKET_SALE_CHECK, money.add(commission), packet.getId(), "创建营销红包");        //是否自动审核通过        SysDict sysDict = sysDictService.selectOne(DictKey.packet_sale_check);        if (Objects.nonNull(sysDict)) {            createSaleSuccess(packet);        }        return FsResponseGen.successData(packet.getId());    }    /**     * 审核拒绝后再通过     *     * @param packetSale     * @return     */    @Override    @Transactional(rollbackFor = Exception.class)    public FsResponse createSaleAgain(PacketSale packetSale) {        //检查余额是否充足 如果是是从余额发起的话        UserBalance balance = balanceService.selectByUserId(packetSale.getUserId());        if (balance.getIncomeBalance().compareTo(packetSale.getMoney().add(packetSale.getCommission())) < 0) {            return FsResponseGen.fail(YiChatMsgCode.PACKET_CREATE_NO_ENOUGH_BALANCE);        }        balanceService.update(packetSale.getUserId(), BalanceType.PACKET_SALE_CHECK, packetSale.getMoney().add(packetSale.getCommission()), packetSale.getId(), "创建营销红包");        //自动审核通过        packetSale.setCheckStatus(CheckStatus.WAIT.getVal());        return createSaleSuccess(packetSale);    }    @Override    @Transactional(rollbackFor = Exception.class)    public FsResponse terminateSale(Long packetId, Long userId) {        PacketSale sale = packetSaleMapper.selectByPrimaryKey(packetId);        //没有权限        if (!Objects.equals(userId, sale.getUserId())) {            return FsResponseGen.fail(YiChatMsgCode.PACKET_NONE);        }        return terminateSale(sale);    }    @Override    public FsResponse terminateMixuan(Long packetId, Long userId) {        PacketMixuan sale = packetMixuanMapper.selectByPrimaryKey(packetId);        //没有权限        if (!Objects.equals(userId, sale.getUserId())) {            return FsResponseGen.fail(YiChatMsgCode.FANLI_NONE);        }        return terminateMixuan(sale);    }    @Override    public FsResponse terminateMixuanAdmin(Long packetId) {        PacketMixuan sale = packetMixuanMapper.selectByPrimaryKey(packetId);        return terminateMixuan(sale);    }    @Override    @Transactional(rollbackFor = Exception.class)    public FsResponse terminateSaleByAdmin(Long packetId) {        PacketSale sale = packetSaleMapper.selectByPrimaryKey(packetId);        return terminateSale(sale);    }    /**     * 终止红包 - 在审核通过、等待审核、暂停状态下可终止     *     * @param sale     * @return     */    private FsResponse terminateSale(PacketSale sale) {        //红包不存在        if (Objects.isNull(sale) || sale.getStatus() == 1) {            return FsResponseGen.fail(YiChatMsgCode.PACKET_NONE);        }        //如果已抢完        if (sale.getOverStatus() == 1) {            return FsResponseGen.fail(YiChatMsgCode.PACKET_FINISHED);        }        Contracts.assertTrue(Objects.equals(CheckStatus.PASS.getVal(), sale.getCheckStatus()) || Objects.equals(CheckStatus.WAIT.getVal(), sale.getCheckStatus()) || Objects.equals(CheckStatus.PAUSE.getVal(), sale.getCheckStatus()), YiChatMsgCode.SYSTEM_ERROR.msg());        //查询未领取红包退回        Example sel = new Example(PacketSaleReceive.class);        sel.createCriteria().andEqualTo("status", 0).andEqualTo("packetId", sale.getId());        List<PacketSaleReceive> re = packetSaleReceiveMapper.selectByExample(sel);        BigDecimal noneReceive = sale.getMoney();        if (GeneralUtils.isNotNullOrEmpty(re)) {            BigDecimal receive = re.stream().map(PacketSaleReceive::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add);            noneReceive = sale.getMoney().subtract(receive);        }        //还未待领取的红包        if (noneReceive.compareTo(BigDecimal.ZERO) > 0) {            logger.debug("红包[{}]还有金额【{}】超时未被领取", sale.getId(), noneReceive);            balanceService.update(sale.getUserId(), BalanceType.PACKET_SALE_TERMINATE_BACK, noneReceive, sale.getUserId(), BalanceType.PACKET_SALE_TERMINATE_BACK.getDesc());        } else {            logger.debug("红包[{}]已被领完", sale.getId());        }        sale.setCheckStatus(CheckStatus.REVOKE.getVal());        sale.setOverStatus(1);        packetSaleMapper.updateByPrimaryKeySelective(sale);        //删除redis key        redisService.deletePacketSaleKey(String.valueOf(sale.getId()));        logger.debug("红包[{}]状态变更为已领完", sale.getId());        return FsResponseGen.successData(getPacketSaleIndexDto(sale));    }    /**     * 终止米选 - 在审核通过、等待审核、暂停状态下可终止     *     * @param sale     * @return     */    private FsResponse terminateMixuan(PacketMixuan sale) {        //红包不存在        if (Objects.isNull(sale) || sale.getStatus() == 1 || sale.getUserType() != 3) {            return FsResponseGen.fail(YiChatMsgCode.FANLI_NONE);        }        //如果已抢完        if (sale.getOverStatus() == 1) {            return FsResponseGen.fail(YiChatMsgCode.FANLI_FINISHED);        }        Contracts.assertTrue(Objects.equals(CheckStatus.PASS.getVal(), sale.getCheckStatus()) || Objects.equals(CheckStatus.WAIT.getVal(), sale.getCheckStatus()) || Objects.equals(CheckStatus.PAUSE.getVal(), sale.getCheckStatus()), YiChatMsgCode.SYSTEM_ERROR.msg());        mixuanBack(sale);        //        logger.debug("红包[{}]状态变更为已领完", sale.getId());        return FsResponseGen.successData(getPacketMixuanDetailDto(sale, null));    }    @Transactional(rollbackFor = Exception.class, isolation = Isolation.SERIALIZABLE)    public void mixuanBack(PacketMixuan sale) {        //查询未领取红包退回        Example sel = new Example(FanliGoodsReceive.class);        //不管什么status都计算        sel.createCriteria().andEqualTo("referId", sale.getId()).andEqualTo("userType", 3);        List<FanliGoodsReceive> re = fanliGoodsReceiveMapper.selectByExample(sel);        BigDecimal noneReceive = countMixuanTotalPrice(sale.getRealMoney(), sale.getNum());        if (GeneralUtils.isNotNullOrEmpty(re)) {            BigDecimal receive = re.stream().map(FanliGoodsReceive::getRealMoney).reduce(BigDecimal.ZERO, BigDecimal::add);            noneReceive = noneReceive.subtract(receive);        }        //还未待领取的红包        if (noneReceive.compareTo(BigDecimal.ZERO) > 0) {//            logger.debug("红包[{}]还有金额【{}】超时未被领取", sale.getId(), noneReceive);            balanceService.update(sale.getUserId(), BalanceType.PACKET_MIXUAN_TERMINATE_BACK, noneReceive, sale.getUserId(), BalanceType.PACKET_SALE_TERMINATE_BACK.getDesc());        } else {//            logger.debug("红包[{}]已被领完", sale.getId());        }        sale.setCheckStatus(CheckStatus.REVOKE.getVal());        sale.setOverStatus(1);        packetMixuanMapper.updateByPrimaryKeySelective(sale);        //删除redis key        redisService.deletePacketMixuanKey(String.valueOf(sale.getId()));    }    @Override    @Transactional(rollbackFor = Exception.class)    public FsResponse toggleSale(Long packetId, Long userId) {        PacketSale sale = packetSaleMapper.selectByPrimaryKey(packetId);        //红包不存在        if (!Objects.equals(userId, sale.getUserId())) {            return FsResponseGen.fail(YiChatMsgCode.PACKET_NONE);        }        return toggleSale(sale);    }    @Override    public FsResponse toggleMixuan(Long packetId, Long userId) {        PacketMixuan sale = packetMixuanMapper.selectByPrimaryKey(packetId);        //红包不存在        if (!Objects.equals(userId, sale.getUserId())) {            return FsResponseGen.fail(YiChatMsgCode.FANLI_NONE);        }        return toggleMixuan(sale);    }    @Override    @Transactional(rollbackFor = Exception.class)    public FsResponse toggleMixuanAdmin(Long packetId) {        PacketMixuan sale = packetMixuanMapper.selectByPrimaryKey(packetId);        return toggleMixuan(sale);    }    @Override    @Transactional(rollbackFor = Exception.class)    public FsResponse toggleSaleAdmin(Long packetId) {        PacketSale sale = packetSaleMapper.selectByPrimaryKey(packetId);        return toggleSale(sale);    }    private FsResponse toggleSale(PacketSale sale) {        //红包不存在        if (Objects.isNull(sale) || sale.getStatus() == 1) {            return FsResponseGen.fail(YiChatMsgCode.PACKET_NONE);        }        //如果已抢完        if (sale.getOverStatus() == 1) {            return FsResponseGen.fail(YiChatMsgCode.PACKET_FINISHED);        }        if (Objects.equals(sale.getCheckStatus(), CheckStatus.PAUSE.getVal())) {            sale.setCheckStatus(CheckStatus.PASS.getVal());        } else if (Objects.equals(sale.getCheckStatus(), CheckStatus.PASS.getVal())) {            sale.setCheckStatus(CheckStatus.PAUSE.getVal());        }        packetSaleMapper.updateByPrimaryKeySelective(sale);        return FsResponseGen.successData(getPacketSaleIndexDto(sale));    }    private FsResponse toggleMixuan(PacketMixuan sale) {        //红包不存在        if (Objects.isNull(sale) || sale.getStatus() == 1 || sale.getUserType() != 3) {            return FsResponseGen.fail(YiChatMsgCode.FANLI_NONE);        }        //如果已抢完        if (sale.getOverStatus() == 1) {            return FsResponseGen.fail(YiChatMsgCode.FANLI_FINISHED);        }        if (Objects.equals(sale.getCheckStatus(), CheckStatus.PAUSE.getVal())) {            sale.setCheckStatus(CheckStatus.PASS.getVal());        } else if (Objects.equals(sale.getCheckStatus(), CheckStatus.PASS.getVal())) {            sale.setCheckStatus(CheckStatus.PAUSE.getVal());        }        packetMixuanMapper.updateByPrimaryKeySelective(sale);        return FsResponseGen.successData(getPacketMixuanDetailDto(sale, null));    }    /**     * 审核通过 - 只有在待审核状态才能通过     *     * @param packetSale     * @return     */    @Override    @Transactional(rollbackFor = Exception.class)    public FsResponse createSaleSuccess(PacketSale packetSale) {        Contracts.assertTrue(Objects.equals(CheckStatus.WAIT.getVal(), packetSale.getCheckStatus()), YiChatMsgCode.SYSTEM_ERROR.msg());        //红包拆分        List<BigDecimal> packets = packetCreateService.constructSale(packetSale.getMoney(), packetSale.getNum());        Collections.sort(packets);        redisService.setPacketSale(String.valueOf(packetSale.getId()), packets);        //营销红包状态更新        PacketSale ps = new PacketSale();        ps.setId(packetSale.getId());        ps.setCheckStatus(CheckStatus.PASS.getVal());        packetSaleMapper.updateByPrimaryKeySelective(ps);        //更新余额        balanceService.update(packetSale.getUserId(), BalanceType.PACKET_SALE_CREATE, packetSale.getMoney().add(packetSale.getCommission() == null ? new BigDecimal("0") : packetSale.getCommission()), packetSale.getId(), "创建营销红包-已创建");        return FsResponseGen.success();    }    /**     * 审核通过 - 只有在待审核状态才能通过     *     * @param packetMixuan     * @return     */    @Override    @Transactional(rollbackFor = Exception.class)    public FsResponse createMixuanSuccess(PacketMixuan packetMixuan) {        Contracts.assertTrue(Objects.equals(CheckStatus.WAIT.getVal(), packetMixuan.getCheckStatus()), YiChatMsgCode.SYSTEM_ERROR.msg());        //红包拆分-平均        BigDecimal value = packetMixuan.getRealMoney();        List<BigDecimal> packets = new ArrayList<>();        for (int i = 0; i < packetMixuan.getNum(); i++) {            packets.add(value);        }        redisService.setPacketMixuan(String.valueOf(packetMixuan.getId()), packets);        //营销红包状态更新        PacketMixuan ps = new PacketMixuan();        ps.setId(packetMixuan.getId());        ps.setCheckStatus(CheckStatus.PASS.getVal());        packetMixuanMapper.updateByPrimaryKeySelective(ps);        //更新余额，余额不变，还在冻结中        //        balanceService.update(packetMixuan.getUserId(), BalanceType.PACKET_MIXUAN_CREATE, packetMixuan.getZkFinalPrice().add(packetMixuan.getCommission() == null ? new BigDecimal("0") : packetMixuan.getCommission()), packetMixuan.getId(), "创建米选-已创建");        return FsResponseGen.success();    }    /**     * 审核拒绝 - 只有在待审核状态才能拒绝     *     * @param packetSale     * @return     */    @Override    @Transactional(rollbackFor = Exception.class)    public FsResponse createSaleFail(PacketSale packetSale) {        Contracts.assertTrue(Objects.equals(CheckStatus.WAIT.getVal(), packetSale.getCheckStatus()), YiChatMsgCode.SYSTEM_ERROR.msg());        PacketSale ps = new PacketSale();        ps.setId(packetSale.getId());        ps.setCheckStatus(CheckStatus.FAILED.getVal());        ps.setRefuseReason(packetSale.getRefuseReason());        packetSaleMapper.updateByPrimaryKeySelective(ps);        //更新余额        balanceService.update(packetSale.getUserId(), BalanceType.PACKET_SALE_BACK, packetSale.getMoney().add(packetSale.getCommission() == null ? new BigDecimal("0") : packetSale.getCommission()), packetSale.getId(), "创建营销红包-审核退回");        return FsResponseGen.success();    }    /**     * 审核拒绝 - 只有在待审核状态才能拒绝     *     * @param packetMixuan     * @return     */    @Override    @Transactional(rollbackFor = Exception.class)    public FsResponse createMixuanFail(PacketMixuan packetMixuan) {        Contracts.assertTrue(Objects.equals(CheckStatus.WAIT.getVal(), packetMixuan.getCheckStatus()), YiChatMsgCode.SYSTEM_ERROR.msg());        PacketMixuan ps = new PacketMixuan();        ps.setId(packetMixuan.getId());        ps.setCheckStatus(CheckStatus.FAILED.getVal());        ps.setRefuseReason(packetMixuan.getRefuseReason());        packetMixuanMapper.updateByPrimaryKeySelective(ps);        //更新余额        BigDecimal money = countMixuanTotalPrice(packetMixuan.getRealMoney(), packetMixuan.getNum());        balanceService.update(packetMixuan.getUserId(), BalanceType.PACKET_MIXUAN_BACK, money.add(packetMixuan.getCommission() == null ? BigDecimal.ZERO : packetMixuan.getCommission()), packetMixuan.getId(), "创建米选-审核退回");        return FsResponseGen.success();    }    @Override    public FsResponse detailSale(Long packetId, Long userId) {        PacketSale copy = packetSaleMapper.selectByPrimaryKey(packetId);        if (Objects.isNull(copy) || copy.getStatus() == 1) {            return FsResponseGen.fail(YiChatMsgCode.PACKET_NONE);        }        return FsResponseGen.successData(getPacketSaleDetailDto(copy, userId));    }    @Override    public FsResponse detailMixuan(Long packetId, Long userId) {        PacketMixuan copy = packetMixuanMapper.selectByPrimaryKey(packetId);        if (Objects.isNull(copy) || copy.getStatus() == 1) {            return FsResponseGen.fail(YiChatMsgCode.FANLI_NONE);        }        if (Objects.equals(copy.getUserId(), userId)) {            return FsResponseGen.successData(getPacketMixuanDetailDto(copy, null));        } else {            return FsResponseGen.successData(getPacketMixuanDetailDto(copy, userId));        }    }    private PacketSaleDetailDto getPacketSaleDetailDto(PacketSale copy, Long userId) {        Integer receiveStatus = -1;        Integer giveStatus = -1;        BigDecimal receiveMoney = BigDecimal.ZERO;        if (Objects.nonNull(userId)) {            Example example = new Example(PacketSaleReceive.class);            example.createCriteria().andEqualTo("userId", userId).andEqualTo("packetId", copy.getId());            PacketSaleReceive receive = packetSaleReceiveMapper.selectOneByExample(example);            receiveStatus = Objects.nonNull(receive) ? 1 : 0;            receiveMoney = Objects.nonNull(receive) ? receive.getMoney() : BigDecimal.ZERO;            giveStatus = Objects.nonNull(receive) ? receive.getStatus() : 0;        }        PacketSaleDetailDto detailDto = new PacketSaleDetailDto();        detailDto.setReceiveStatus(receiveStatus);        detailDto.setQuestion(copy.getQuestion());        detailDto.setAnswer(copy.getAnswer());        detailDto.setTip(copy.getTip());        detailDto.setOverStatus(copy.getOverStatus());        detailDto.setName(copy.getName());        detailDto.setNum(copy.getNum());        detailDto.setReceiveNum(copy.getUserCount());        detailDto.setImgs(copy.getImgs());        detailDto.setPacketId(copy.getId());        detailDto.setContent(copy.getContent());        detailDto.setMoney(copy.getMoney());        detailDto.setVideo(copy.getVideo());        detailDto.setContactStatus(copy.getContactStatus());        detailDto.setLinkUrl(copy.getLinkUrl());        detailDto.setThumbnail(copy.getThumbnail());        detailDto.setLocation(copy.getLocation());        detailDto.setLimitDistance(copy.getLimitDistance());        detailDto.setExternal(copy.getExternal());        detailDto.setReceiveMoney(receiveMoney);        detailDto.setGiveStatus(giveStatus);        detailDto.setLinkUrlStatus(copy.getLinkUrlStatus());        return detailDto;    }    /**     * 详情，如果有userId说明是某个用户查看详情，否则是创建者查看详情     *     * @param copy     * @return     */    private PacketMixuanIndexDto getPacketMixuanDetailDto(PacketMixuan copy, Long userId) {        PacketMixuanIndexDto detailDto = new PacketMixuanIndexDto();        if (Objects.nonNull(userId)) {            Integer receiveStatus;            BigDecimal receiveMoney;            Example example = new Example(FanliGoodsReceive.class);            example.createCriteria().andEqualTo("userId", userId).andEqualTo("referId", copy.getId()).andEqualTo("userType", 3);            FanliGoodsReceive receive = fanliGoodsReceiveMapper.selectOneByExample(example);            receiveStatus = Objects.nonNull(receive) ? receive.getStatus() : -1;            receiveMoney = Objects.nonNull(receive) ? receive.getRealMoney() : BigDecimal.ZERO;            detailDto.setReceiveMoney(receiveMoney);            detailDto.setReceiveStatus(receiveStatus);        } else {            detailDto.setCheckStatus(copy.getCheckStatus());            detailDto.setCommission(copy.getCommission());            detailDto.setNum(copy.getNum());            detailDto.setUserId(copy.getUserId());            detailDto.setReceiveNum(copy.getUserCount());        }        detailDto.setItemId(copy.getReferId());        detailDto.setCommissionRate(String.valueOf(copy.getCommissionRate()));        detailDto.setZkFinalPrice(copy.getZkFinalPrice());        detailDto.setReservePrice(copy.getReservePrice());        detailDto.setUserType(copy.getUserType());        detailDto.setCouponAmount(copy.getCouponAmount());        detailDto.setCouponShareUrl(copy.getCouponShareUrl());        detailDto.setCtime(copy.getCtime());        detailDto.setId(copy.getId());        detailDto.setOverStatus(copy.getOverStatus());        detailDto.setLatitude(copy.getLatitude());        detailDto.setLongitude(copy.getLongitude());        if (StringUtils.isNotEmpty(copy.getPictUrl()) && !copy.getPictUrl().contains("http")) {            copy.setPictUrl("http:" + copy.getPictUrl());        }        detailDto.setPictUrl(copy.getPictUrl());        String smallImgs = copy.getSmallImages();        if (StringUtils.isNotEmpty(smallImgs))            detailDto.setSmallImages(JSONArray.parseArray(smallImgs, String.class));        else {            detailDto.setSmallImages(new ArrayList<>());        }        detailDto.setTitle(copy.getTitle());        detailDto.setUrl(copy.getUrl());        detailDto.setLocation(copy.getLocation());        detailDto.setLimitDistance(copy.getLimitDistance());        return detailDto;    }    /**     * 米选列表     *     * @param copy     * @return     */    private PacketMixuanIndexDto getPacketMixuanIndexDto(PacketMixuan copy) {        PacketMixuanIndexDto detailDto = new PacketMixuanIndexDto();        detailDto.setItemId(copy.getReferId());        detailDto.setCommissionRate(String.valueOf(copy.getCommissionRate()));        detailDto.setZkFinalPrice(copy.getZkFinalPrice());        detailDto.setReservePrice(copy.getReservePrice());        detailDto.setUserType(copy.getUserType());        detailDto.setCouponAmount(copy.getCouponAmount());        detailDto.setCouponShareUrl(copy.getCouponShareUrl());        detailDto.setCtime(copy.getCtime());        detailDto.setId(copy.getId());        detailDto.setOverStatus(copy.getOverStatus());        detailDto.setLatitude(copy.getLatitude());        detailDto.setLongitude(copy.getLongitude());        if (StringUtils.isNotEmpty(copy.getPictUrl()) && !copy.getPictUrl().contains("http")) {            copy.setPictUrl("http:" + copy.getPictUrl());        }        detailDto.setPictUrl(copy.getPictUrl());        String smallImgs = copy.getSmallImages();        if (StringUtils.isNotEmpty(smallImgs))            detailDto.setSmallImages(JSONArray.parseArray(smallImgs, String.class));        else {            detailDto.setSmallImages(new ArrayList<>());        }        detailDto.setTitle(copy.getTitle());        detailDto.setUrl(copy.getUrl());        detailDto.setLocation(copy.getLocation());        detailDto.setLimitDistance(copy.getLimitDistance());        return detailDto;    }    /**     * 和接口发送营销红包列表返回一致     */    private PacketSaleIndexDto getPacketSaleIndexDto(PacketSale copy) {        PacketSaleIndexDto dto = new PacketSaleIndexDto();        dto.setPacketId(copy.getId());        dto.setContent(copy.getContent());        dto.setMoney(copy.getMoney());        dto.setExternal(copy.getExternal());        dto.setOverStatus(copy.getOverStatus());        dto.setCheckStatus(copy.getCheckStatus());        dto.setRefuseReason(copy.getRefuseReason());        dto.setName(copy.getName());        dto.setNum(copy.getNum());        dto.setReceiveNum(copy.getUserCount());        dto.setUserId(copy.getUserId());        dto.setImgs(copy.getImgs());        dto.setVideo(copy.getVideo());        dto.setThumbnail(copy.getThumbnail());        dto.setLinkUrl(copy.getLinkUrl());        dto.setLinkUrlStatus(copy.getLinkUrlStatus());        dto.setContactStatus(copy.getContactStatus());        //        dto.setUsernick(copy.get());        //        dto.setAvatar(copy.get());        dto.setCtimeDesc(DateUtils.formatDate(copy.getCtime()));        return dto;    }    @Override    @Transactional(rollbackFor = Exception.class)    public FsResponse receiveSale(Long packetId, Long userId, BigDecimal longitiude, BigDecimal latitude) {        User user = userService.selectById(userId);        Example example = new Example(PacketSaleReceive.class);        example.createCriteria().andEqualTo("userId", userId);        List<PacketSaleReceive> receiveList = packetSaleReceiveMapper.selectByExample(example);        //查询今天领取的红包次数        Example example2 = new Example(PacketSaleReceive.class);        example2.createCriteria().andEqualTo("userId", userId).andBetween("ctime", DateUtils.formatDate(new Date(), "yyyy-MM-dd 00:00:00"), DateUtils.formatDate(new Date(), "yyyy-MM-dd 23:59:59"));        int todayCount = packetSaleReceiveMapper.selectCountByExample(example2);        //查询当前积分等级        SysDictData level = userIntegralService.selectLevel(user.getIntegral());        //是否超出当前等级限制数        if (Integer.parseInt(level.getMemo()) <= todayCount) {            return FsResponseGen.fail(YiChatMsgCode.PACKET_LEVEL_LIMIT);        }        //查询是否存在已抢过        if (receiveList.stream().anyMatch(v -> v.getPacketId().compareTo(packetId) == 0)) {            return FsResponseGen.fail(YiChatMsgCode.PACKET_RECEIVE_REPEAT);        }        PacketSale packet = packetSaleMapper.selectByPrimaryKey(packetId);        if (Objects.isNull(packet) || packet.getStatus() == 1) {            return FsResponseGen.fail(YiChatMsgCode.PACKET_NONE);        }        //查看是否有距离限制        if (Optional.ofNullable(packet.getLimitDistance()).orElse(0) > 0 && Objects.nonNull(packet.getLatitude()) && Objects.nonNull(packet.getLongitude())) {            if (GeneralUtils.getDistance(latitude, longitiude, packet.getLatitude(), packet.getLongitude()) > packet.getLimitDistance() * 1000) {                return FsResponseGen.fail(YiChatMsgCode.PACKET_LEVEL_DISTANCE);            }        }        //抢红包当前人获取金额        //如果是老用户，低于平均值        BigDecimal money;        if (userService.validOldUser(null, null, 4, userId)) {            money = redisService.getSalePacket(String.valueOf(packetId), userId, 1);        } else {            if (receiveList.size() == 0) {                money = redisService.getSalePacket(String.valueOf(packetId), userId, 3);            } else {                money = redisService.getSalePacket(String.valueOf(packetId), userId, 0);            }        }        if (Objects.isNull(money) || money.compareTo(BigDecimal.ZERO) == 0) {            return FsResponseGen.fail(YiChatMsgCode.PACKET_RECEIVE_NONE);        }        //营销红包人数增加        packetSaleMapper.addUserCount(packetId);        //增加记录        PacketSaleReceive record = new PacketSaleReceive();        record.setMoney(money);        record.setUserId(userId);        record.setPacketId(packetId);        //sale.type：0 广告红包（直接到账） 1 商品返利（需要审核） 2视频里的商品返利（需要审核）        if (packet.getType() == 0) {            record.setStatus(1);        } else {            record.setStatus(0);        }        packetSaleReceiveMapper.insertSelective(record);        if (packet.getType() == 0) {            balanceService.update(userId, BalanceType.PACKET_SALE_GET, money, packet.getId(), "领取营销红包");        } else {            balanceService.update(userId, BalanceType.PACKET_SALE_GET_CHECK, money, packet.getId(), "领取商品返利");        }        //领完红包后判断下是否已领完        if (redisService.getSalePacketSize(String.valueOf(packetId)) == 0) {            packet.setOverStatus(1);            packetSaleMapper.updateByPrimaryKeySelective(packet);        }        return FsResponseGen.successData(getPacketSaleDetailDto(packet, userId));    }    @Override    public FsResponse receiveMixuan(Long packetId, Long userId, BigDecimal longitiude, BigDecimal latitude) {        Example example = new Example(FanliGoodsReceive.class);        example.createCriteria().andEqualTo("userId", userId).andEqualTo("userType", 3).andEqualTo("referId", packetId);        List<FanliGoodsReceive> receiveList = fanliGoodsReceiveMapper.selectByExample(example);        //查询是否存在已抢过        if (receiveList.stream().anyMatch(v -> Objects.equals(String.valueOf(packetId), v.getReferId()))) {            return FsResponseGen.fail(YiChatMsgCode.PACKET_RECEIVE_REPEAT);        }        PacketMixuan packet = packetMixuanMapper.selectByPrimaryKey(packetId);        if (Objects.isNull(packet) || packet.getStatus() == 1) {            return FsResponseGen.fail(YiChatMsgCode.FANLI_NONE);        }        //查看是否有距离限制        if (Optional.ofNullable(packet.getLimitDistance()).orElse(0) > 0 && Objects.nonNull(packet.getLatitude()) && Objects.nonNull(packet.getLongitude())) {            if (GeneralUtils.getDistance(latitude, longitiude, packet.getLatitude(), packet.getLongitude()) > packet.getLimitDistance() * 1000) {                return FsResponseGen.fail(YiChatMsgCode.FANLI_LEVEL_DISTANCE);            }        }        //抢红包当前人获取金额        BigDecimal money = redisService.getMixuanPacket(String.valueOf(packetId), userId, 0);        if (Objects.isNull(money) || money.compareTo(BigDecimal.ZERO) == 0) {            return FsResponseGen.fail(YiChatMsgCode.FANLI_RECEIVE_NONE);        }        //营销红包人数增加        packetMixuanMapper.addUserCount(packetId);        //增加记录        FanliGoodsReceive record = new FanliGoodsReceive();        record.setUserId(userId);        //0 待提交  1待审核 2已返利 3已拒绝        record.setStatus(0);        record.setCtime(new Date());        record.setRealMoney(money);        record.setCommissionRate(packet.getCommissionRate());        record.setReferId(String.valueOf(packetId));        record.setUserType(packet.getUserType());        record.setZkFinalPrice(packet.getZkFinalPrice());        record.setReservePrice(packet.getReservePrice());        record.setPictUrl(packet.getPictUrl());        record.setTitle(packet.getTitle());        record.setUrl(packet.getUrl());        record.setSmallImages(packet.getSmallImages());        record.setCouponAmount(packet.getCouponAmount());        record.setCouponShareUrl(packet.getCouponShareUrl());        fanliGoodsReceiveMapper.insertSelective(record);        //领完红包后判断下是否已领完        if (redisService.getMixuanPacketSize(String.valueOf(packetId)) == 0) {            packet.setOverStatus(1);            packetMixuanMapper.updateByPrimaryKeySelective(packet);        }        return FsResponseGen.successData(getPacketMixuanDetailDto(packet, userId));    }    @Override    public FsResponse giveSale(Long packetId, Long userId, Long ownerUserId) {        PacketSale packetSale = packetSaleMapper.selectByPrimaryKey(packetId);        Contracts.assertTrue(Objects.equals(packetSale.getUserId(), ownerUserId), "无权操作");        Example example = new Example(PacketReceive.class);        example.createCriteria().andEqualTo("packetId", packetId).andEqualTo("userId", userId);        PacketSaleReceive receive = packetSaleReceiveMapper.selectOneByExample(example);        if (Objects.isNull(receive)) {            return FsResponseGen.failMsg("记录不存在");        }        receive.setStatus(1);        packetSaleReceiveMapper.updateByPrimaryKey(receive);        balanceService.update(userId, BalanceType.PACKET_SALE_GET_SUCCESS, receive.getMoney(), packetId, "发放商品返利");        return FsResponseGen.successData(receive.getMoney());    }    @Override    public FsResponse saleList(Integer pageNo, Integer pageSize, Long userId, Integer type, Long packetId, BigDecimal longitude, BigDecimal latitude) {        //PageHelper.startPage(1, 1);        //如果不是今天第一次看红包，则第一个红包展示置顶红包        Example example2 = new Example(PacketSaleView.class);        example2.createCriteria().andEqualTo("userId", userId).andBetween("ctime", DateUtils.formatDate(new Date(), "yyyy-MM-dd 00:00:00"), DateUtils.formatDate(new Date(), "yyyy-MM-dd 23:59:59"));        int viewCount = packetSaleViewMapper.selectCountByExample(example2);        Long sort = null;        if (viewCount == 0) {            sort = 1l;        }        //如果不是指定的红包,则去除已领完的红包        List<PacketSaleIndexDto> saleList = Optional.ofNullable(packetSaleMapper.selectSuccessList(userId, packetId, sort)).orElse(new ArrayList<>());        //如果不是分享的，剔除老用户可看的红包、剔除超出距离的红包        if (Objects.isNull(packetId)) {            boolean old = userService.validOldUser(null, 2, null, userId);            if (!old) {                saleList = saleList.stream().filter(p -> !Objects.equals(PacketSaleType.OLD_USER.getVal(), p.getAd())).collect(Collectors.toList());            }            saleList = saleList.stream().filter(packet -> {                //查看是否有距离限制                if (Optional.ofNullable(packet.getLimitDistance()).orElse(0) > 0 && Objects.nonNull(packet.getLatitude()) && Objects.nonNull(packet.getLongitude())) {                    if (Objects.isNull(latitude) || Objects.isNull(longitude)) {                        return false;                    }                    if (GeneralUtils.getDistance(latitude, longitude, packet.getLatitude(), packet.getLongitude()) > packet.getLimitDistance() * 1000) {                        return false;                    }                }                return true;            }).collect(Collectors.toList());        }        //只取一个,因为存在看过红包的逻辑        if (saleList.size() > 0) {            saleList = saleList.subList(0, 1);        } else {            saleList = Optional.ofNullable(packetSaleMapper.selectDefaultList(userId, sort)).orElse(new ArrayList<>());        }        return DtoChangeUtils.getPageList(saleList, v -> {            Integer receiveStatus = -1;            BigDecimal receiveMoney = BigDecimal.ZERO;            if (Objects.nonNull(userId)) {                Example ex = new Example(PacketSaleReceive.class);                ex.createCriteria().andEqualTo("userId", userId).andEqualTo("packetId", v.getPacketId());                PacketSaleReceive receive = packetSaleReceiveMapper.selectOneByExample(ex);                receiveStatus = Objects.nonNull(receive) ? 1 : 0;                receiveMoney = Objects.nonNull(receive) ? receive.getMoney() : BigDecimal.ZERO;            }            v.setReceiveMoney(receiveMoney);            v.setReceiveStatus(receiveStatus);            if (Objects.nonNull(userId)) {                viewSale(userId, v.getPacketId());            }            return v;        });    }    @Override    public FsResponse mixuanList(FsPage page, Long userId) {        PageHelper.startPage(page.getPageNo(), page.getPageSize());        //如果不是指定的红包,则去除已领完的红包        List<PacketMixuan> saleList = Optional.ofNullable(packetMixuanMapper.selectList(userId, 1l)).orElse(new ArrayList<>());        return DtoChangeUtils.getPageList(saleList, v -> getPacketMixuanIndexDto(v));    }    @Override    public FsResponse mixuanDaily() {        Example example = new Example(PacketMixuan.class);        example.createCriteria().andNotEqualTo("userType", 3).andBetween("ctime", DateUtils.formatDate(new Date(), "yyyy-MM-dd 00:00:00"), DateUtils.formatDate(new Date(), "yyyy-MM-dd 23:59:59")).andEqualTo("checkStatus", 1).andEqualTo("status", 0);        List<PacketMixuan> mixuanList = packetMixuanMapper.selectByExample(example);        FanliListResp dto = new FanliListResp();        if (mixuanList.size() > 0) {            DtoChangeUtils.getDto(mixuanList.get(0), v -> {                dto.setItemId(v.getReferId());                String smallImgs = v.getSmallImages();                if (StringUtils.isNotEmpty(smallImgs)) {                    dto.setSmallImages(JSONArray.parseArray(smallImgs, String.class));                } else {                    dto.setSmallImages(new ArrayList<>());                }                dto.setPictUrl(v.getPictUrl());                dto.setUserType(v.getUserType());                dto.setUrl(v.getUrl());                dto.setTitle(v.getTitle());                dto.setCouponShareUrl(v.getCouponShareUrl());                dto.setCouponAmount(v.getCouponAmount());                dto.setReservePrice(String.valueOf(v.getReservePrice()));                dto.setCommissionRate(String.valueOf(v.getCommissionRate()));                dto.setZkFinalPrice(String.valueOf(v.getZkFinalPrice()));                return dto;            });        }        return FsResponseGen.successData(dto);    }    @Override    public FsResponse mixuanApplyList(FsPage page, Long userId, Long packetId) {        PageHelper.startPage(page.getPageNo(), page.getPageNo());        List<FanliGiveAndGoodsDetailDto> list = fanliGoodsGiveMapper.selectMixuanApplyList(userId, packetId == null ? null : String.valueOf(packetId));        return DtoChangeUtils.getPageList(list, v -> fanliService.getFanliGiveAndReceiveDetailDto(v));    }    @Override    public void quitGroupSale(Long userId, Integer groupId) {        //查询群是否绑定红包        Example example = new Example(PacketSale.class);        example.createCriteria().andEqualTo("groupId", groupId);        List<PacketSale> list = packetSaleMapper.selectByExample(example);        //如果是有时间限制红包金额到可提现 查询当前用户是否抢到金额        if (GeneralUtils.isNotNullOrEmpty(list)) {            for (PacketSale sale : list) {                Example ex = new Example(PacketSaleReceive.class);                ex.createCriteria().andEqualTo("userId", userId).andEqualTo("packetId", sale.getId());                PacketSaleReceive receive = packetSaleReceiveMapper.selectOneByExample(ex);                //查询抢红包金额                if (Objects.isNull(receive)) {                    continue;                }                if (sale.getLimitMinutes() > 0) {                    //查看进群时间是否超过限制                    RcGroupMembers groupMember = groupService.selectGroupMember(groupId, userId);                    //已经超过时间  符合转可提现条件                    if (groupMember.getTimestamp() / 6000 >= sale.getLimitMinutes()) {                        balanceService.update(userId, BalanceType.PACKET_SALE_GET_FREEZE_NOT, receive.getMoney(), sale.getId(), "红包金额转可提现");                    } else {                        //不符合条件 金额退换给商家用户                        balanceService.update(sale.getUserId(), BalanceType.PACKET_SALE_GET_FREEZE_OWNER_END, receive.getMoney(), sale.getId(), "营销红包用户退群返还");                        balanceService.update(userId, BalanceType.PACKET_SALE_GET_FREEZE_USER_END, receive.getMoney(), sale.getId(), "营销红包退群扣除");                    }                }            }        }    }    @Override    public FsResponse saleAuth(Long userId, Integer groupId) {        //查看当前群是否绑定已存在的营销红包        Example example = new Example(PacketSale.class);        example.createCriteria().andEqualTo("groupId", groupId).andEqualTo("status", 0).andLessThanOrEqualTo("endTime", DateUtils.formatCurrentDate());        //存在未结束的活动        if (GeneralUtils.isNotNullOrEmpty(packetSaleMapper.selectByExample(example))) {            return FsResponseGen.failMsg("已存在正在运行的营销红包");        }        return FsResponseGen.success();    }    @Override    @Async    public void viewSale(Long userId, Long packetId) {        packetSaleViewMapper.updateSave(userId, packetId);    }    @Override    public FsResponse saleChartList(Long userId) {        SaleChartDto dto = new SaleChartDto();        //当前用户收益        Random random = new Random();        dto.setBalance(Optional.ofNullable(balanceService.selectTotalByType(userId, BalanceType.PACKET_SALE_GET)).orElse(BigDecimal.ZERO));        dto.setOrderNum(10000 + balanceService.selectOrderNum(dto.getBalance()));        List<SaleChartItem> chartItems = balanceService.selectChartList();        chartItems = chartItems.stream().map(v -> {            double d = random.nextDouble() * 1500 + 500;            v.setInviteEarn(NumberUtils.halfTwo(new BigDecimal(d)));            v.setTotalEarn(v.getInviteEarn().add(v.getPacketEarn()));            return v;        }).sorted(Comparator.comparing(SaleChartItem::getTotalEarn).reversed()).collect(Collectors.toList());        dto.setList(DtoChangeUtils.getList(chartItems, v -> v));        //排行榜数据        return FsResponseGen.successData(dto);    }    @Override    public FsResponse saleChartList2(Long userId) {        SaleChartDto dto = new SaleChartDto();        if (Objects.isNull(userId)) {            //当前用户收益            dto.setBalance(BigDecimal.ZERO);            dto.setOrderNum(9999l);        } else {            //当前用户收益            dto.setBalance(Optional.ofNullable(balanceService.selectTotalByType(userId, BalanceType.PACKET_SALE_GET)).orElse(BigDecimal.ZERO));            dto.setOrderNum(10000 + balanceService.selectOrderNum(dto.getBalance()));        }        dto.setList(DtoChangeUtils.getList(balanceService.selectChartList(), v -> {            v.setInviteEarn(BigDecimal.ZERO);            return v;        }));        //排行榜数据        return FsResponseGen.successData(dto);    }    /**     * 申请视频红包，如果存在未领取的红包,则返回。否则新增一个待领取的红包并返回     * TODO 所有用户都可申请红包     *     * @param userId     * @return     */    @Override    public FsResponse applyVideoPacket(Long userId) {        Example example = new Example(PacketVideo.class);        example.createCriteria().andEqualTo("userId", userId).andEqualTo("status", 0);        PacketVideo packetVideo = packetVideoMapper.selectOneByExample(example);        if (Objects.isNull(packetVideo)) {            packetVideo = new PacketVideo();            Date currentDate = new Date();            packetVideo.setCtime(currentDate);            Integer time = getLimitTime(userId);            if (Objects.isNull(time)) {                return FsResponseGen.fail(YiChatMsgCode.PACKET_LEVEL_LIMIT);            }            packetVideo.setLimitTime(time);            packetVideo.setStatus(0);            packetVideo.setUserId(userId);            packetVideoMapper.insertSelective(packetVideo);        }        return FsResponseGen.successData(getPakcetVideoDto(packetVideo));    }    private PacketVideoDto getPakcetVideoDto(PacketVideo packetVideo) {        PacketVideoDto dto = new PacketVideoDto();        dto.setPacketId(packetVideo.getId());        dto.setMoney(packetVideo.getMoney());        dto.setLimitTime(packetVideo.getLimitTime());        dto.setCreateTimeDesc(DateUtils.formatDate(packetVideo.getCtime()));        dto.setReceiveTimeDesc(DateUtils.formatDate(packetVideo.getReceiveTime()));        return dto;    }    /**     * 领取视频红包。一个用户最多只会有一个未领取的视频红包     *     * @param userId     * @return     */    @Override    @Transactional(rollbackFor = Exception.class)    public FsResponse receiveVideoPacket(Long userId) {        Example example = new Example(PacketVideo.class);        example.createCriteria().andEqualTo("userId", userId).andEqualTo("status", 0);        PacketVideo packetVideo = packetVideoMapper.selectOneByExample(example);        if (Objects.isNull(packetVideo)) {            return FsResponseGen.failMsg("红包不存在");        }        Date currentDate = new Date();        int interval = (int) DateUtils.getDistanceSeconds(packetVideo.getCtime(), currentDate);        if (interval < packetVideo.getLimitTime()) {            return FsResponseGen.failMsg("未到领取时间");        }        //领取成功，更新红包和余额        BigDecimal money = getPacketVideoMoney(userId);        packetVideo.setStatus(1);        packetVideo.setReceiveTime(currentDate);        packetVideo.setMoney(money);        packetVideoMapper.updateByPrimaryKey(packetVideo);        balanceService.update(userId, BalanceType.VIDEO_PACKET, money, null, "领取视频红包");        return FsResponseGen.successData(getPakcetVideoDto(packetVideo));    }    /**     * 领取vip红包     *     * @param userId     * @return     */    @Override    @Transactional(rollbackFor = Exception.class)    public FsResponse receiveVipPacket(Long userId) {        User user = userService.selectById(userId);        //查询今天领取的红包次数        Example example = new Example(PacketVipReceive.class);        example.createCriteria().andEqualTo("userId", userId).andBetween("ctime", DateUtils.formatDate(new Date(), "yyyy-MM-dd 00:00:00"), DateUtils.formatDate(new Date(), "yyyy-MM-dd 23:59:59"));        int todayCount = packetVipReceiveMapper.selectCountByExample(example);        //查询当前会员积分等级        SysDictData level = userIntegralService.selectLevel(user.getIntegral());        //是否超出当前等级限制数        if (Integer.parseInt(level.getMemo()) <= todayCount) {            return FsResponseGen.fail(YiChatMsgCode.PACKET_LEVEL_LIMIT);        }        //连续领了两天却没有造成返利，不给红包        Example example2 = new Example(PacketVipReceive.class);        example2.createCriteria().andEqualTo("userId", userId).andBetween("ctime", DateUtils.formatDate(DateUtils.getPrevDay(1), "yyyy-MM-dd 00:00:00"), DateUtils.formatDate(DateUtils.getPrevDay(1), "yyyy-MM-dd 23:59:59"));        int yesterdayCount = packetVipReceiveMapper.selectCountByExample(example2);        if (yesterdayCount > 0) {            Example example3 = new Example(PacketVipReceive.class);            example3.createCriteria().andEqualTo("userId", userId).andBetween("ctime", DateUtils.formatDate(DateUtils.getPrevDay(2), "yyyy-MM-dd 00:00:00"), DateUtils.formatDate(DateUtils.getPrevDay(2), "yyyy-MM-dd 23:59:59"));            int threeDaysAgoCount = packetVipReceiveMapper.selectCountByExample(example3);            if (threeDaysAgoCount > 0) {                Example fanliExample = new Example(FanliGoodsGive.class);                fanliExample.createCriteria().andEqualTo("userId", userId).andEqualTo("status", 1);                List<FanliGoodsGive> fanliGoodsGives = fanliGoodsGiveMapper.selectByExample(fanliExample);                if (fanliGoodsGives.size() == 0) {                    return FsResponseGen.failMsg("领取返利将会获得更多红包哦~");                }            }        }        //获取红包金额        BigDecimal money = getPacketVipMoney(userId, level);        //插入领取列表        PacketVipReceive receive = new PacketVipReceive();        receive.setCtime(new Date());        receive.setMoney(money);        receive.setUserId(userId);        packetVipReceiveMapper.insertSelective(receive);        //领取成功，更新红包和余额        balanceService.update(userId, BalanceType.VIP_PACKET_RECEIVE, money, null, "会员领取红包");        return FsResponseGen.successData(money);    }    @Override    public List<PacketReceiveDto> receiveList(Long packetId) {        List<PacketReceiveDto> list = packetReceiveMapper.selectReceiveList(packetId);        list.forEach(v -> {            try {                v.setUserId(N3d.encode(v.getUserIdL()));            } catch (Exception e) {                e.printStackTrace();            }        });        return list;    }    /**     * 获取领取视频红包限制时长（秒）     *     * @param userId     * @return     */    private Integer getLimitTime(Long userId) {        Example example = new Example(PacketVideo.class);        example.createCriteria().andEqualTo("userId", userId).andEqualTo("status", 1).andBetween("ctime", DateUtils.formatDate(new Date(), "yyyy-MM-dd 00:00:00"), DateUtils.formatDate(new Date(), "yyyy-MM-dd 23:59:59"));        int count = packetVideoMapper.selectCountByExample(example);        //        int type = 0;        //        //今天申请的前10个红包时长低于平均，其他随机        //        if (count < 10) {        //            type = 1;        //        }        //        Integer time = redisService.getPacketVideoTime(String.valueOf(userId), type);        //        //强制重置、领完、或者第一次领会出现，根据count重新分配红包        //        if (Objects.isNull(time)) {        //            redisService.setUserPacketVideo(String.valueOf(userId), count);        //            time = redisService.getPacketVideoTime(String.valueOf(userId), type);        //        }        count++;        int time = count * 20;        time = Math.max(20, time);        time = Math.min(3600, time);        return time;    }    /**     * 获取领取视频红包金额     *     * @param userId     * @return     */    private BigDecimal getPacketVideoMoney(Long userId) {        Example example = new Example(PacketVideo.class);        example.createCriteria().andEqualTo("userId", userId).andEqualTo("status", 1).andBetween("ctime", DateUtils.formatDate(new Date(), "yyyy-MM-dd 00:00:00"), DateUtils.formatDate(new Date(), "yyyy-MM-dd 23:59:59"));        int count = packetVideoMapper.selectCountByExample(example);        int type = 0;        //今天申请的前10个红包金额高于平均，其他随机        if (count < 10) {            type = 2;        }        //由于时间变为固定的了，所以此处需要money做size=0的处理了        BigDecimal money = redisService.getPacketVideoMoney(String.valueOf(userId), type);        if (BigDecimal.ZERO.compareTo(money) == 0) {            redisService.setUserPacketVideo(String.valueOf(userId), count);            money = redisService.getPacketVideoMoney(String.valueOf(userId), type);        }        return money;    }    /**     * 获取vip红包金额     *     * @return     */    private BigDecimal getPacketVipMoney(Long userId, SysDictData level) {        int sort = level.getSort();        int type;        if (sort == 1) {            type = 0;        } else if (sort > 4) {            type = 2;        } else {            type = 1;        }        BigDecimal money = redisService.getPacketVipMoney(String.valueOf(userId), type);        if (BigDecimal.ZERO.compareTo(money) == 0) {            reGivePacketVip(level, userId);            money = redisService.getPacketVipMoney(String.valueOf(userId), type);        }        return money;    }    /**     * 发放vip红包     */    private void reGivePacketVip(SysDictData level, Long userId) {        Example example = new Example(PacketVipRule.class);        example.createCriteria().andEqualTo("status", 1).andEqualTo("dictDataId", level.getId());        PacketVipRule rule = packetVipRuleMapper.selectOneByExample(example);        if (Objects.nonNull(rule)) {            //查询已领取的次数和金额            PacketSendInfoDto dto = packetVipReceiveMapper.selectReceiveCount(userId);            BigDecimal restMoney = rule.getTotalMoney().subtract(Optional.ofNullable(dto.getMoney()).orElse(BigDecimal.ZERO));            Integer restNum = rule.getNum() - Optional.ofNullable(dto.getCount()).orElse(0);            restMoney = restMoney.compareTo(BigDecimal.ZERO) > 0 ? restMoney : BigDecimal.ZERO;            //已经超出该等级可领次数            Contracts.assertTrue(restNum > 0, "-1" + "=" + level.getName() + "会员领取红包次数累计已达上限");            List<BigDecimal> moneyList = packetCreateService.constructVideoPacket(restMoney, restNum, rule.getMinMoney(), rule.getMaxMoney());            redisService.resetPacketVip(moneyList, userId);        }    }    @Override    @Transactional(rollbackFor = Exception.class)    public FsResponse createMixuan(Long userId, PacketMixuan mixuan) {        Contracts.assertNotNull(mixuan.getZkFinalPrice(), YiChatMsgCode.SYSTEM_PARAM_ERROR.msg());        Contracts.assertNotNull(mixuan.getNum(), YiChatMsgCode.SYSTEM_PARAM_ERROR.msg());        Contracts.assertNotNull(mixuan.getUserType(), YiChatMsgCode.SYSTEM_PARAM_ERROR.msg());        Contracts.assertNotNull(mixuan.getPictUrl(), YiChatMsgCode.SYSTEM_PARAM_ERROR.msg());        Contracts.assertNotNull(mixuan.getTitle(), YiChatMsgCode.SYSTEM_PARAM_ERROR.msg());        Contracts.assertNotNull(mixuan.getUrl(), YiChatMsgCode.SYSTEM_PARAM_ERROR.msg());        //单价四舍五入        BigDecimal price = mixuan.getZkFinalPrice().compareTo(BigDecimal.ZERO) > 0 ? mixuan.getZkFinalPrice() : BigDecimal.ZERO;        price.setScale(2, BigDecimal.ROUND_HALF_UP);        mixuan.setZkFinalPrice(price);        if (Objects.isNull(mixuan.getReservePrice())) {            mixuan.setReservePrice(mixuan.getZkFinalPrice());        }        if (StringUtils.isEmpty(mixuan.getCouponAmount())) {            mixuan.setCouponAmount("0");        }        //返佣不能超过10000        if (Objects.isNull(mixuan.getCommissionRate()) || mixuan.getCommissionRate().compareTo(10000) > 0) {            mixuan.setCommissionRate(10000);        }        //计算最终需要扣除的单价（类似返利价格）        BigDecimal unitPrice = fanliService.countFanliMoney(mixuan.getZkFinalPrice(), new BigDecimal(mixuan.getCouponAmount()), mixuan.getCommissionRate());        if (unitPrice.compareTo(BigDecimal.ZERO) <= 0) {            return FsResponseGen.failMsg("客单价小于0");        }        //个数取绝对值        mixuan.setNum(Math.abs(mixuan.getNum()));        //userType固定为3        mixuan.setUserType(3);        //主体数据保存        Date currentDate = new Date();        //待审核        mixuan.setCheckStatus(CheckStatus.WAIT.getVal());        mixuan.setStatus(0);        mixuan.setCtime(currentDate);        mixuan.setRealMoney(unitPrice);        mixuan.setUserId(userId);        mixuan.setUserCount(0);        mixuan.setOverStatus(0);        mixuan.setId(null);        //检查余额是否充足 如果是是从余额发起的话        UserBalance balance = balanceService.selectByUserId(userId);        BigDecimal money = countMixuanTotalPrice(unitPrice, mixuan.getNum());        //手续费        BigDecimal commission = new BigDecimal(Optional.ofNullable(sysDictService.selectOne(DictKey.packet_mixuan_commission)).map(SysDict::getValue).orElse("0"));        commission = NumberUtils.halfTwo(money.multiply(commission));        //判断余额是否足够        if (balance.getIncomeBalance().compareTo(money.add(commission)) < 0) {            return FsResponseGen.fail(YiChatMsgCode.PACKET_CREATE_NO_ENOUGH_BALANCE);        }        //减去手续费        //money = money.subtract(commission);        if (money.compareTo(NumberUtils.scale2HalfUp(new BigDecimal(0.01).multiply(new BigDecimal(1)))) < 0) {            return FsResponseGen.fail(YiChatMsgCode.PACKET_CREATE_MONEY_LIMIT);        }        balanceService.update(userId, BalanceType.PACKET_MIXUAN_CHECK, money.add(commission), mixuan.getId(), "创建米选");        mixuan.setCommission(commission);        packetMixuanMapper.insertUseGeneratedKeys(mixuan);        //是否自动审核通过        SysDict sysDict = sysDictService.selectOne(DictKey.packet_mixuan_check);        if (Objects.nonNull(sysDict)) {            createMixuanSuccess(mixuan);        }        return FsResponseGen.successData(mixuan.getId());    }    /**     * 审核拒绝后再通过     *     * @return     */    @Override    @Transactional(rollbackFor = Exception.class)    public FsResponse createMixuanAgain(PacketMixuan mixuan) {        //检查余额是否充足 如果是是从余额发起的话        UserBalance balance = balanceService.selectByUserId(mixuan.getUserId());        BigDecimal money = countMixuanTotalPrice(mixuan.getRealMoney(), mixuan.getNum());        //手续费        BigDecimal commission = new BigDecimal(Optional.ofNullable(sysDictService.selectOne(DictKey.packet_mixuan_commission)).map(SysDict::getValue).orElse("0"));        commission = NumberUtils.halfTwo(money.multiply(commission));        //判断余额是否足够        if (balance.getIncomeBalance().compareTo(money.add(commission)) < 0) {            return FsResponseGen.fail(YiChatMsgCode.PACKET_CREATE_NO_ENOUGH_BALANCE);        }        //减去手续费        //money = money.subtract(commission);        if (money.compareTo(NumberUtils.scale2HalfUp(new BigDecimal(0.01).multiply(new BigDecimal(1)))) < 0) {            return FsResponseGen.fail(YiChatMsgCode.PACKET_CREATE_MONEY_LIMIT);        }        balanceService.update(mixuan.getUserId(), BalanceType.PACKET_MIXUAN_CHECK, money.add(commission), mixuan.getId(), "创建米选");        //自动审核通过        mixuan.setCheckStatus(CheckStatus.WAIT.getVal());        return createMixuanSuccess(mixuan);    }    /**     * 根据单价和数量计算总价，向上舍入     *     * @param zkFinalPrice     * @param num     * @return     */    private BigDecimal countMixuanTotalPrice(BigDecimal zkFinalPrice, Integer num) {        BigDecimal total = NumberUtils.halfTwo(zkFinalPrice.multiply(new BigDecimal(String.valueOf(num)))).setScale(2, BigDecimal.ROUND_UP);        return total.compareTo(BigDecimal.ZERO) > 0 ? total : BigDecimal.ZERO;    }}